[WAN]: Remove broken and unmaintained Sangoma drivers.

The in-kernel Sangoma drivers are both not compiling and marked as BROKEN
since at least kernel 2.6.0.

Sangoma offers out-of-tree drivers, and David Mandelstam told me Sangoma
does no longer maintain the in-kernel drivers and prefers to provide them
as a separate installation package.

This patch therefore removes these drivers.

Signed-off-by: Adrian Bunk <bunk@stusta.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/MAINTAINERS b/MAINTAINERS
index d00dea5..6d3c401 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3058,13 +3058,6 @@
 L:	lm-sensors@lm-sensors.org
 S:	Odd Fixes
 
-WAN ROUTER & SANGOMA WANPIPE DRIVERS & API (X.25, FRAME RELAY, PPP, CISCO HDLC)
-P:	Nenad Corbic
-M:	ncorbic@sangoma.com
-M:	dm@sangoma.com
-W:	http://www.sangoma.com
-S:	Supported
-
 WATCHDOG DEVICE DRIVERS
 P:	Wim Van Sebroeck
 M:	wim@iguana.be
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 883cf7d..b5328b0 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -410,103 +410,6 @@
 
 	  If unsure, say N.
 
-config VENDOR_SANGOMA
-	tristate "Sangoma WANPIPE(tm) multiprotocol cards"
-	depends on WAN_ROUTER_DRIVERS && WAN_ROUTER && (PCI || ISA) && BROKEN
-	---help---
-	  Driver for S514-PCI/ISA Synchronous Data Link Adapters (SDLA).
-
-	  WANPIPE from Sangoma Technologies Inc. <http://www.sangoma.com/>
-	  is a family of intelligent multiprotocol WAN adapters with data
-	  transfer rates up to 4Mbps. Cards support:
-
-	  - X.25, Frame Relay, PPP, Cisco HDLC protocols.
-
-	  - API for protocols like HDLC (LAPB), HDLC Streaming, X.25,
-	  Frame Relay and BiSync.
-
-	  - Ethernet Bridging over Frame Relay protocol.
-
-	  - MULTILINK PPP
-
-	  - Async PPP (Modem Dialup)
-
-	  The next questions will ask you about the protocols you want
-	  the driver to support.
-
-	  If you have one or more of these cards, say M to this option;
-	  and read <file:Documentation/networking/wan-router.txt>.
-
-	  To compile this driver as a module, choose M here: the
-	  module will be called wanpipe.
-
-config WANPIPE_CHDLC
-	bool "WANPIPE Cisco HDLC support"
-	depends on VENDOR_SANGOMA
-	---help---
-	  Connect a WANPIPE card to a leased line using the Cisco HDLC.
-
-	  - Supports Dual Port Cisco HDLC on the S514-PCI/S508-ISA cards
-	  which allows user to build applications using the HDLC streaming API.
-
-	  - CHDLC Streaming MULTILINK PPP that can bind multiple WANPIPE T1
-	  cards into a single logical channel.
-
-	  Say Y and the Cisco HDLC support, HDLC streaming API and
-	  MULTILINK PPP will be included in the driver.
-
-config WANPIPE_FR
-	bool "WANPIPE Frame Relay support"
-	depends on VENDOR_SANGOMA
-	help
-	  Connect a WANPIPE card to a Frame Relay network, or use Frame Relay
-	  API to develop custom applications.
-
-	  Contains the Ethernet Bridging over Frame Relay feature, where
-	  a WANPIPE frame relay link can be directly connected to the Linux
-	  kernel bridge. The Frame Relay option is supported on S514-PCI
-	  and S508-ISA cards.
-
-	  Say Y and the Frame Relay support will be included in the driver.
-
-config WANPIPE_X25
-	bool "WANPIPE X.25 support"
-	depends on VENDOR_SANGOMA
-	help
-	  Connect a WANPIPE card to an X.25 network.
-
-	  Includes the X.25 API support for custom applications over the
-	  X.25 protocol. The X.25 option is supported on S514-PCI and
-	  S508-ISA cards.
-
-	  Say Y and the X.25 support will be included in the driver.
-
-config WANPIPE_PPP
-	bool "WANPIPE PPP support"
-	depends on VENDOR_SANGOMA
-	help
-	  Connect a WANPIPE card to a leased line using Point-to-Point
-	  Protocol (PPP).
-
-	  The PPP option is supported on S514-PCI/S508-ISA cards.
-
-	  Say Y and the PPP support will be included in the driver.
-
-config WANPIPE_MULTPPP
-	bool "WANPIPE Multi-Port PPP support"
-	depends on VENDOR_SANGOMA
-	help
-	  Connect a WANPIPE card to a leased line using Point-to-Point
-	  Protocol (PPP).
-
-	  Uses in-kernel SyncPPP protocol over the Sangoma HDLC Streaming
-	  adapter. In this case each Sangoma adapter port can support an
-	  independent PPP connection. For example, a single Quad-Port PCI
-	  adapter can support up to four independent PPP links. The PPP
-	  option is supported on S514-PCI/S508-ISA cards.
-
-	  Say Y and the Multi-Port PPP support will be included in the driver.
-
 config CYCLADES_SYNC
 	tristate "Cyclom 2X(tm) cards (EXPERIMENTAL)"
 	depends on WAN_ROUTER_DRIVERS && (PCI || ISA)
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index ce6c56b..823c6d5 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -5,14 +5,6 @@
 # Rewritten to use lists instead of if-statements.
 #
 
-wanpipe-y			:= sdlamain.o sdla_ft1.o
-wanpipe-$(CONFIG_WANPIPE_X25)	+= sdla_x25.o
-wanpipe-$(CONFIG_WANPIPE_FR)	+= sdla_fr.o
-wanpipe-$(CONFIG_WANPIPE_CHDLC)	+= sdla_chdlc.o
-wanpipe-$(CONFIG_WANPIPE_PPP)	+= sdla_ppp.o
-wanpipe-$(CONFIG_WANPIPE_MULTPPP) += wanpipe_multppp.o
-wanpipe-objs			:= $(wanpipe-y)
-
 cyclomx-y                       := cycx_main.o
 cyclomx-$(CONFIG_CYCLOMX_X25)	+= cycx_x25.o
 cyclomx-objs			:= $(cyclomx-y)  
@@ -43,11 +35,6 @@
 
 obj-$(CONFIG_DLCI)		+= dlci.o 
 obj-$(CONFIG_SDLA)		+= sdla.o
-ifeq ($(CONFIG_WANPIPE_MULTPPP),y)
-  obj-$(CONFIG_VENDOR_SANGOMA) += sdladrv.o wanpipe.o syncppp.o	
-else
-  obj-$(CONFIG_VENDOR_SANGOMA) += sdladrv.o wanpipe.o
-endif
 obj-$(CONFIG_CYCLADES_SYNC)	+= cycx_drv.o cyclomx.o
 obj-$(CONFIG_LAPBETHER)		+= lapbether.o
 obj-$(CONFIG_SBNI)		+= sbni.o
diff --git a/drivers/net/wan/sdla_chdlc.c b/drivers/net/wan/sdla_chdlc.c
deleted file mode 100644
index 496d292..0000000
--- a/drivers/net/wan/sdla_chdlc.c
+++ /dev/null
@@ -1,4428 +0,0 @@
-/*****************************************************************************
-* sdla_chdlc.c	WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module.
-*
-* Authors: 	Nenad Corbic <ncorbic@sangoma.com>
-*		Gideon Hack  
-*
-* Copyright:	(c) 1995-2001 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.
-* ============================================================================
-* Feb 28, 2001  Nenad Corbic	Updated if_tx_timeout() routine for 
-* 				2.4.X kernels.
-* Jan 25, 2001  Nenad Corbic	Added a TTY Sync serial driver over the
-* 				HDLC streaming protocol
-* 				Added a TTY Async serial driver over the
-* 				Async protocol.
-* Dec 15, 2000  Nenad Corbic    Updated for 2.4.X Kernel support
-* Nov 13, 2000  Nenad Corbic    Added true interface type encoding option.
-* 				Tcpdump doesn't support CHDLC inteface
-* 				types, to fix this "true type" option will set
-* 				the interface type to RAW IP mode.
-* Nov 07, 2000  Nenad Corbic	Added security features for UDP debugging:
-*                               Deny all and specify allowed requests.
-* Jun 20, 2000  Nenad Corbic	Fixed the API IP ERROR bug. Caused by the 
-*                               latest update.
-* May 09, 2000	Nenad Corbic	Option to bring down an interface
-*                               upon disconnect.
-* Mar 23, 2000  Nenad Corbic	Improved task queue, bh handling.
-* Mar 16, 2000	Nenad Corbic	Fixed the SLARP Dynamic IP addressing.
-* Mar 06, 2000  Nenad Corbic	Bug Fix: corrupted mbox recovery.
-* Feb 10, 2000  Gideon Hack     Added ASYNC support.
-* Feb 09, 2000  Nenad Corbic    Fixed two shutdown bugs in update() and
-*                               if_stats() functions.
-* Jan 24, 2000  Nenad Corbic    Fixed a startup wanpipe state racing,  
-*                               condition between if_open and isr. 
-* Jan 10, 2000  Nenad Corbic    Added new socket API support.
-* Dev 15, 1999  Nenad Corbic    Fixed up header files for 2.0.X kernels
-* Nov 20, 1999  Nenad Corbic 	Fixed zero length API bug.
-* Sep 30, 1999  Nenad Corbic    Fixed dynamic IP and route setup.
-* Sep 23, 1999  Nenad Corbic    Added SMP support, fixed tracing 
-* Sep 13, 1999  Nenad Corbic	Split up Port 0 and 1 into separate devices.
-* Jun 02, 1999  Gideon Hack     Added support for the S514 adapter.
-* Oct 30, 1998	Jaspreet Singh	Added Support for CHDLC API (HDLC STREAMING).
-* Oct 28, 1998	Jaspreet Singh	Added Support for Dual Port CHDLC.
-* Aug 07, 1998	David Fong	Initial version.
-*****************************************************************************/
-
-#include <linux/module.h>
-#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/slab.h>	/* kmalloc(), kfree() */
-#include <linux/wanrouter.h>	/* WAN router definitions */
-#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
-#include <linux/if_arp.h>	/* ARPHRD_* defines */
-
-
-#include <asm/uaccess.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-
-#include <linux/in.h>		/* sockaddr_in */
-#include <linux/inet.h>	
-#include <linux/if.h>
-#include <asm/byteorder.h>	/* htons(), etc. */
-#include <linux/sdlapci.h>
-#include <asm/io.h>
-
-#include <linux/sdla_chdlc.h>		/* CHDLC firmware API definitions */
-#include <linux/sdla_asy.h>           	/* CHDLC (async) API definitions */
-
-#include <linux/if_wanpipe_common.h>    /* Socket Driver common area */
-#include <linux/if_wanpipe.h>		
-
-/* TTY Includes */
-#include <linux/tty.h>
-#include <linux/tty_flip.h>
-#include <linux/serial.h>
-
-
-/****** Defines & Macros ****************************************************/
-
-/* reasons for enabling the timer interrupt on the adapter */
-#define TMR_INT_ENABLED_UDP   		0x01
-#define TMR_INT_ENABLED_UPDATE		0x02
-#define TMR_INT_ENABLED_CONFIG		0x10
-
-#define MAX_IP_ERRORS	10
-
-#define TTY_CHDLC_MAX_MTU	2000
-#define	CHDLC_DFLT_DATA_LEN	1500		/* default MTU */
-#define CHDLC_HDR_LEN		1
-
-#define CHDLC_API 0x01
-
-#define PORT(x)   (x == 0 ? "PRIMARY" : "SECONDARY" )
-#define MAX_BH_BUFF	10
-
-//#define PRINT_DEBUG
-#ifdef PRINT_DEBUG
-#define dbg_printk(format, a...) printk(format, ## a)
-#else
-#define dbg_printk(format, a...)
-#endif  
-
-/******Data Structures*****************************************************/
-
-/* This structure is placed in the private data area of the device structure.
- * The card structure used to occupy the private area but now the following 
- * structure will incorporate the card structure along with CHDLC specific data
- */
-
-typedef struct chdlc_private_area
-{
-	wanpipe_common_t common;
-	sdla_t		*card;
-	int 		TracingEnabled;		/* For enabling Tracing */
-	unsigned long 	curr_trace_addr;	/* Used for Tracing */
-	unsigned long 	start_trace_addr;
-	unsigned long 	end_trace_addr;
-	unsigned long 	base_addr_trace_buffer;
-	unsigned long 	end_addr_trace_buffer;
-	unsigned short 	number_trace_elements;
-	unsigned  	available_buffer_space;
-	unsigned long 	router_start_time;
-	unsigned char 	route_status;
-	unsigned char 	route_removed;
-	unsigned long 	tick_counter;		/* For 5s timeout counter */
-	unsigned long 	router_up_time;
-        u32             IP_address;		/* IP addressing */
-        u32             IP_netmask;
-	u32		ip_local;
-	u32		ip_remote;
-	u32 		ip_local_tmp;
-	u32		ip_remote_tmp;
-	u8		ip_error;
-	u8		config_chdlc;
-	u8 		config_chdlc_timeout;
-	unsigned char  mc;			/* Mulitcast support on/off */
-	unsigned short udp_pkt_lgth;		/* udp packet processing */
-	char udp_pkt_src;
-	char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
-	unsigned short timer_int_enabled;
-	char update_comms_stats;		/* updating comms stats */
-
-	bh_data_t *bh_head;	  	  /* Circular buffer for chdlc_bh */
-	unsigned long  tq_working;
-	volatile int  bh_write;
-	volatile int  bh_read;
-	atomic_t  bh_buff_used;
-	
-	unsigned char interface_down;
-
-	/* Polling work queue entry. Each interface
-         * has its own work queue entry, which is used
-         * to defer events from the interrupt */
-	struct work_struct poll_work;
-	struct timer_list poll_delay_timer;
-
-	u8 gateway;
-	u8 true_if_encoding;
-	//FIXME: add driver stats as per frame relay!
-
-} chdlc_private_area_t;
-
-/* Route Status options */
-#define NO_ROUTE	0x00
-#define ADD_ROUTE	0x01
-#define ROUTE_ADDED	0x02
-#define REMOVE_ROUTE	0x03
-
-
-/* variable for keeping track of enabling/disabling FT1 monitor status */
-static int rCount = 0;
-
-/* variable for tracking how many interfaces to open for WANPIPE on the
-   two ports */
-
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-/****** Function Prototypes *************************************************/
-/* WAN link driver entry points. These are called by the WAN router module. */
-static int update(struct wan_device* wandev);
-static int new_if(struct wan_device* wandev, struct net_device* dev,
-		  wanif_conf_t* conf);
-
-/* Network device interface */
-static int if_init(struct net_device* dev);
-static int if_open(struct net_device* dev);
-static int if_close(struct net_device* dev);
-static int if_header(struct sk_buff* skb, struct net_device* dev,
-		     unsigned short type, void* daddr, void* saddr,
-		     unsigned len);
-
-static int if_rebuild_hdr (struct sk_buff *skb);
-static struct net_device_stats* if_stats(struct net_device* dev);
-  
-static int if_send(struct sk_buff* skb, struct net_device* dev);
-
-/* CHDLC Firmware interface functions */
-static int chdlc_configure 	(sdla_t* card, void* data);
-static int chdlc_comm_enable 	(sdla_t* card);
-static int chdlc_read_version 	(sdla_t* card, char* str);
-static int chdlc_set_intr_mode 	(sdla_t* card, unsigned mode);
-static int chdlc_send (sdla_t* card, void* data, unsigned len);
-static int chdlc_read_comm_err_stats (sdla_t* card);
-static int chdlc_read_op_stats (sdla_t* card);
-static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
-
-
-static int chdlc_disable_comm_shutdown (sdla_t *card);
-static void if_tx_timeout(struct net_device *dev);
-
-/* Miscellaneous CHDLC Functions */
-static int set_chdlc_config (sdla_t* card);
-static void init_chdlc_tx_rx_buff( sdla_t* card);
-static int process_chdlc_exception(sdla_t *card);
-static int process_global_exception(sdla_t *card);
-static int update_comms_stats(sdla_t* card,
-        chdlc_private_area_t* chdlc_priv_area);
-static int configure_ip (sdla_t* card);
-static int unconfigure_ip (sdla_t* card);
-static void process_route(sdla_t *card);
-static void port_set_state (sdla_t *card, int);
-static int config_chdlc (sdla_t *card);
-static void disable_comm (sdla_t *card);
-
-static void trigger_chdlc_poll(struct net_device *dev);
-static void chdlc_poll(struct net_device *dev);
-static void chdlc_poll_delay (unsigned long dev_ptr);
-
-
-/* Miscellaneous asynchronous interface Functions */
-static int set_asy_config (sdla_t* card);
-static int asy_comm_enable (sdla_t* card);
-
-/* Interrupt handlers */
-static void wpc_isr (sdla_t* card);
-static void rx_intr (sdla_t* card);
-static void timer_intr(sdla_t *);
-
-/* Bottom half handlers */
-static void chdlc_work(struct net_device *dev);
-static int chdlc_work_cleanup(struct net_device *dev);
-static int bh_enqueue(struct net_device *dev, struct sk_buff *skb);
-
-/* Miscellaneous functions */
-static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev,
-				struct sk_buff *skb);
-static int reply_udp( unsigned char *data, unsigned int mbox_len );
-static int intr_test( sdla_t* card);
-static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
-static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
-                                struct sk_buff *skb, struct net_device* dev,
-                                chdlc_private_area_t* chdlc_priv_area);
-static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,  
-				chdlc_private_area_t* chdlc_priv_area);
-static unsigned short calc_checksum (char *, int);
-static void s508_lock (sdla_t *card, unsigned long *smp_flags);
-static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
-
-
-static int  Intr_test_counter;
-
-/* TTY Global Definitions */
-
-#define NR_PORTS 4
-#define WAN_TTY_MAJOR 226
-#define WAN_TTY_MINOR 0
-
-#define WAN_CARD(port) (tty_card_map[port])
-#define MIN_PORT 0
-#define MAX_PORT NR_PORTS-1 
-
-#define CRC_LENGTH 2
-
-static int wanpipe_tty_init(sdla_t *card);
-static void wanpipe_tty_receive(sdla_t *, unsigned, unsigned int);
-static void wanpipe_tty_trigger_poll(sdla_t *card);
-
-static struct tty_driver serial_driver;
-static int tty_init_cnt=0;
-
-static struct serial_state rs_table[NR_PORTS];
-
-static char tty_driver_mode=WANOPT_TTY_SYNC;
-
-static char *opt_decode[] = {"NONE","CRTSCTS","XONXOFF-RX",
-	  	             "CRTSCTS XONXOFF-RX","XONXOFF-TX",
-		             "CRTSCTS XONXOFF-TX","CRTSCTS XONXOFF"};
-static char *p_decode[] = {"NONE","ODD","EVEN"};
-
-static void* tty_card_map[NR_PORTS] = {NULL,NULL,NULL,NULL};
-
-
-/****** Public Functions ****************************************************/
-
-/*============================================================================
- * Cisco HDLC protocol initialization routine.
- *
- * This routine is called by the main WANPIPE module during setup.  At this
- * point adapter is completely initialized and 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 wpc_init (sdla_t* card, wandev_conf_t* conf)
-{
-	unsigned char port_num;
-	int err;
-	unsigned long max_permitted_baud = 0;
-	SHARED_MEMORY_INFO_STRUCT *flags;
-
-	union
-		{
-		char str[80];
-		} u;
-	volatile CHDLC_MAILBOX_STRUCT* mb;
-	CHDLC_MAILBOX_STRUCT* mb1;
-	unsigned long timeout;
-
-	/* Verify configuration ID */
-	if (conf->config_id != WANCONFIG_CHDLC) {
-		printk(KERN_INFO "%s: invalid configuration ID %u!\n",
-				  card->devname, conf->config_id);
-		return -EINVAL;
-	}
-
-	/* Find out which Port to use */
-	if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
-		if (card->next){
-
-			if (conf->comm_port != card->next->u.c.comm_port){
-				card->u.c.comm_port = conf->comm_port;
-			}else{
-				printk(KERN_INFO "%s: ERROR - %s port used!\n",
-        		        	card->wandev.name, PORT(conf->comm_port));
-				return -EINVAL;
-			}
-		}else{
-			card->u.c.comm_port = conf->comm_port;
-		}
-	}else{
-		printk(KERN_INFO "%s: ERROR - Invalid Port Selected!\n",
-                			card->wandev.name);
-		return -EINVAL;
-	}
-	
-
-	/* Initialize protocol-specific fields */
-	if(card->hw.type != SDLA_S514){
-
-		if (card->u.c.comm_port == WANOPT_PRI){	
-			card->mbox  = (void *) card->hw.dpmbase;
-		}else{
-			card->mbox  = (void *) card->hw.dpmbase + 
-				SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
-		}	
-	}else{ 
-		/* for a S514 adapter, set a pointer to the actual mailbox in the */
-		/* allocated virtual memory area */
-		if (card->u.c.comm_port == WANOPT_PRI){
-			card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
-		}else{
-			card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
-		}	
-	}
-
-	mb = mb1 = card->mbox;
-
-	if (!card->configured){
-
-		/* The board will place an 'I' in the return code to indicate that it is
-	   	ready to accept commands.  We expect this to be completed in less
-           	than 1 second. */
-
-		timeout = jiffies;
-		while (mb->return_code != 'I')	/* Wait 1s for board to initialize */
-			if ((jiffies - timeout) > 1*HZ) break;
-
-		if (mb->return_code != 'I') {
-			printk(KERN_INFO
-				"%s: Initialization not completed by adapter\n",
-				card->devname);
-			printk(KERN_INFO "Please contact Sangoma representative.\n");
-			return -EIO;
-		}
-	}
-
-	/* 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 (chdlc_read_version(card, u.str))
-		return -EIO;
-
-	printk(KERN_INFO "%s: Running Cisco HDLC firmware v%s\n",
-		card->devname, u.str); 
-
-	card->isr			= &wpc_isr;
-	card->poll			= NULL;
-	card->exec			= NULL;
-	card->wandev.update		= &update;
- 	card->wandev.new_if		= &new_if;
-	card->wandev.del_if		= NULL;
-	card->wandev.udp_port   	= conf->udp_port;
-	card->disable_comm		= &disable_comm;
-	card->wandev.new_if_cnt = 0;
-
-	/* reset the number of times the 'update()' proc has been called */
-	card->u.c.update_call_count = 0;
-	
-	card->wandev.ttl = conf->ttl;
-	card->wandev.interface = conf->interface; 
-
-	if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
-	    card->hw.type != SDLA_S514){
-		printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n",
-			card->devname, PORT(card->u.c.comm_port));
-		return -EIO;
-	}
-
-	card->wandev.clocking = conf->clocking;
-
-	port_num = card->u.c.comm_port;
-
-	/* in API mode, we can configure for "receive only" buffering */
-	if(card->hw.type == SDLA_S514) {
-		card->u.c.receive_only = conf->receive_only;
-		if(conf->receive_only) {
-			printk(KERN_INFO
-				"%s: Configured for 'receive only' mode\n",
-                                card->devname);
-		}
-	}
-
-	/* Setup Port Bps */
-
-	if(card->wandev.clocking) {
-		if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
-			/* For Primary Port 0 */
-               		max_permitted_baud =
-				(card->hw.type == SDLA_S514) ?
-				PRI_MAX_BAUD_RATE_S514 : 
-				PRI_MAX_BAUD_RATE_S508;
-
-		}else if(port_num == WANOPT_SEC) {
-			/* For Secondary Port 1 */
-                        max_permitted_baud =
-                               (card->hw.type == SDLA_S514) ?
-                                SEC_MAX_BAUD_RATE_S514 :
-                                SEC_MAX_BAUD_RATE_S508;
-                        }
-  
-			if(conf->bps > max_permitted_baud) {
-				conf->bps = max_permitted_baud;
-				printk(KERN_INFO "%s: Baud too high!\n",
-					card->wandev.name);
- 				printk(KERN_INFO "%s: Baud rate set to %lu bps\n", 
-					card->wandev.name, max_permitted_baud);
-			}
-			card->wandev.bps = conf->bps;
-	}else{
-        	card->wandev.bps = 0;
-  	}
-
-	/* Setup the Port MTU */
-	if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
-
-		/* For Primary Port 0 */
-		card->wandev.mtu =
-			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
-			min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
-			CHDLC_DFLT_DATA_LEN;
-	} else if(port_num == WANOPT_SEC) { 
-		/* For Secondary Port 1 */
-		card->wandev.mtu =
-			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
-			min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
-			CHDLC_DFLT_DATA_LEN;
-	}
-
-	/* Set up the interrupt status area */
-	/* Read the CHDLC Configuration and obtain: 
-	 *	Ptr to shared memory infor struct
-         * Use this pointer to calculate the value of card->u.c.flags !
- 	 */
-	mb1->buffer_length = 0;
-	mb1->command = READ_CHDLC_CONFIGURATION;
-	err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
-	if(err != COMMAND_OK) {
-                if(card->hw.type != SDLA_S514)
-                	enable_irq(card->hw.irq);
-
-		chdlc_error(card, err, mb1);
-		return -EIO;
-	}
-
-	if(card->hw.type == SDLA_S514){
-               	card->u.c.flags = (void *)(card->hw.dpmbase +
-               		(((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
-			ptr_shared_mem_info_struct));
-        }else{
-                card->u.c.flags = (void *)(card->hw.dpmbase +
-                        (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
-			ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
-	}
-
-	flags = card->u.c.flags;
-	
-	/* This is for the ports link state */
-	card->wandev.state = WAN_DUALPORT;
-	card->u.c.state = WAN_DISCONNECTED;
-
-
-	if (!card->wandev.piggyback){	
-		int err;
-
-		/* Perform interrupt testing */
-		err = intr_test(card);
-
-		if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { 
-			printk(KERN_INFO "%s: Interrupt test failed (%i)\n",
-					card->devname, Intr_test_counter);
-			printk(KERN_INFO "%s: Please choose another interrupt\n",
-					card->devname);
-			return -EIO;
-		}
-		
-		printk(KERN_INFO "%s: Interrupt test passed (%i)\n", 
-				card->devname, Intr_test_counter);
-		card->configured = 1;
-	}
-
-	if ((card->tty_opt=conf->tty) == WANOPT_YES){
-		int err;
-		card->tty_minor = conf->tty_minor;
-
-		/* On ASYNC connections internal clocking 
-		 * is mandatory */
-		if ((card->u.c.async_mode = conf->tty_mode)){
-			card->wandev.clocking = 1;
-		}
-		err=wanpipe_tty_init(card);
-		if (err){
-			return err;
-		}
-	}else{
-	
-
-		if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
-			printk (KERN_INFO "%s: "
-				"Failed to set interrupt triggers!\n",
-				card->devname);
-			return -EIO;	
-        	}
-	
-		/* Mask the Timer interrupt */
-		flags->interrupt_info_struct.interrupt_permission &= 
-			~APP_INT_ON_TIMER;
-	}
-
-	/* If we are using CHDLC in backup mode, this flag will
-	 * indicate not to look for IP addresses in config_chdlc()*/
-	card->u.c.backup = conf->backup;
-	
-	printk(KERN_INFO "\n");
-
-	return 0;
-}
-
-/******* WAN Device Driver Entry Points *************************************/
-
-/*============================================================================
- * Update device status & statistics
- * This procedure is called when updating the PROC file system and returns
- * various communications statistics. These statistics are accumulated from 3 
- * different locations:
- * 	1) The 'if_stats' recorded for the device.
- * 	2) Communication error statistics on the adapter.
- *      3) CHDLC operational statistics on the adapter.
- * The board level statistics are read during a timer interrupt. Note that we 
- * read the error and operational statistics during consecitive timer ticks so
- * as to minimize the time that we are inside the interrupt handler.
- *
- */
-static int update(struct wan_device* wandev)
-{
-	sdla_t* card = wandev->private;
- 	struct net_device* dev;
-        volatile chdlc_private_area_t* chdlc_priv_area;
-        SHARED_MEMORY_INFO_STRUCT *flags;
-	unsigned long timeout;
-
-	/* sanity checks */
-	if((wandev == NULL) || (wandev->private == NULL))
-		return -EFAULT;
-	
-	if(wandev->state == WAN_UNCONFIGURED)
-		return -ENODEV;
-
-	/* more sanity checks */
-        if(!card->u.c.flags)
-                return -ENODEV;
-
-	if(test_bit(PERI_CRIT, (void*)&card->wandev.critical))
-                return -EAGAIN;
-
-	if((dev=card->wandev.dev) == NULL)
-		return -ENODEV;
-
-	if((chdlc_priv_area=dev->priv) == NULL)
-		return -ENODEV;
-
-      	flags = card->u.c.flags;
-       	if(chdlc_priv_area->update_comms_stats){
-		return -EAGAIN;
-	}
-			
-	/* we will need 2 timer interrupts to complete the */
-	/* reading of the statistics */
-	chdlc_priv_area->update_comms_stats = 2;
-       	flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
-	chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
-  
-	/* wait a maximum of 1 second for the statistics to be updated */ 
-        timeout = jiffies;
-        for(;;) {
-		if(chdlc_priv_area->update_comms_stats == 0)
-			break;
-                if ((jiffies - timeout) > (1 * HZ)){
-    			chdlc_priv_area->update_comms_stats = 0;
- 			chdlc_priv_area->timer_int_enabled &=
-				~TMR_INT_ENABLED_UPDATE; 
- 			return -EAGAIN;
-		}
-        }
-
-	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(struct wan_device* wandev, struct net_device* dev,
-		  wanif_conf_t* conf)
-{
-	sdla_t* card = wandev->private;
-	chdlc_private_area_t* chdlc_priv_area;
-
-
-	printk(KERN_INFO "%s: Configuring Interface: %s\n",
-			card->devname, conf->name);
- 
-	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 */
-	chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
-	
-	if(chdlc_priv_area == NULL) 
-		return -ENOMEM;
-
-	memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
-
-	chdlc_priv_area->card = card; 
-	chdlc_priv_area->common.sk = NULL;
-	chdlc_priv_area->common.func = NULL;	
-
-	/* initialize data */
-	strcpy(card->u.c.if_name, conf->name);
-
-	if(card->wandev.new_if_cnt > 0) {
-                kfree(chdlc_priv_area);
-		return -EEXIST;
-	}
-
-	card->wandev.new_if_cnt++;
-
-	chdlc_priv_area->TracingEnabled = 0;
-	chdlc_priv_area->route_status = NO_ROUTE;
-	chdlc_priv_area->route_removed = 0;
-
-	card->u.c.async_mode = conf->async_mode;
-	
-	/* setup for asynchronous mode */
-	if(conf->async_mode) {
-		printk(KERN_INFO "%s: Configuring for asynchronous mode\n",
-			wandev->name);
-
-		if(card->u.c.comm_port == WANOPT_PRI) {
-			printk(KERN_INFO
-				"%s:Asynchronous mode on secondary port only\n",
-					wandev->name);
-			kfree(chdlc_priv_area);
-			return -EINVAL;
-		}
-
-	       	if(strcmp(conf->usedby, "WANPIPE") == 0) {
-			printk(KERN_INFO
-                                "%s: Running in WANIPE Async Mode\n",                                        			wandev->name);
-			card->u.c.usedby = WANPIPE;
-		}else{
-			card->u.c.usedby = API;
-		}
-
-		if(!card->wandev.clocking) {
-			printk(KERN_INFO
-				"%s: Asynch. clocking must be 'Internal'\n",
-				wandev->name);
-			kfree(chdlc_priv_area);
-			return -EINVAL;
-		}
-
-		if((card->wandev.bps < MIN_ASY_BAUD_RATE) ||
-			(card->wandev.bps > MAX_ASY_BAUD_RATE)) {
-			printk(KERN_INFO "%s: Selected baud rate is invalid.\n",
-				wandev->name);
-			printk(KERN_INFO "Must be between %u and %u bps.\n",
-				MIN_ASY_BAUD_RATE, MAX_ASY_BAUD_RATE);
-			kfree(chdlc_priv_area);
-			return -EINVAL;
-		}
-
-		card->u.c.api_options = 0;
-                if (conf->asy_data_trans == WANOPT_YES) {
-                        card->u.c.api_options |= ASY_RX_DATA_TRANSPARENT;
-                }
-		
-		card->u.c.protocol_options = 0;
-		if (conf->rts_hs_for_receive == WANOPT_YES) {
-			card->u.c.protocol_options |= ASY_RTS_HS_FOR_RX;
-	        }
-                if (conf->xon_xoff_hs_for_receive == WANOPT_YES) {
-                        card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_RX;
-                }
-                if (conf->xon_xoff_hs_for_transmit == WANOPT_YES) {
-                        card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_TX;
-                }
-                if (conf->dcd_hs_for_transmit == WANOPT_YES) {
-                        card->u.c.protocol_options |= ASY_DCD_HS_FOR_TX;
-                }
-                if (conf->cts_hs_for_transmit == WANOPT_YES) {
-                        card->u.c.protocol_options |= ASY_CTS_HS_FOR_TX;
-                }
-
-		card->u.c.tx_bits_per_char = conf->tx_bits_per_char;
-                card->u.c.rx_bits_per_char = conf->rx_bits_per_char;
-                card->u.c.stop_bits = conf->stop_bits;
-		card->u.c.parity = conf->parity;
-		card->u.c.break_timer = conf->break_timer;
-		card->u.c.inter_char_timer = conf->inter_char_timer;
-		card->u.c.rx_complete_length = conf->rx_complete_length;
-		card->u.c.xon_char = conf->xon_char;
-
-	} else {	/* setup for synchronous mode */
-
-		card->u.c.protocol_options = 0;
-		if (conf->ignore_dcd == WANOPT_YES){
-			card->u.c.protocol_options |= IGNORE_DCD_FOR_LINK_STAT;
-		}
-		if (conf->ignore_cts == WANOPT_YES){
-			card->u.c.protocol_options |= IGNORE_CTS_FOR_LINK_STAT;
-		}
-
-		if (conf->ignore_keepalive == WANOPT_YES) {
-			card->u.c.protocol_options |=
-				IGNORE_KPALV_FOR_LINK_STAT;
-			card->u.c.kpalv_tx  = MIN_Tx_KPALV_TIMER; 
-			card->u.c.kpalv_rx  = MIN_Rx_KPALV_TIMER; 
-			card->u.c.kpalv_err = MIN_KPALV_ERR_TOL; 
-
-		} else {   /* Do not ignore keepalives */
-			card->u.c.kpalv_tx =
-				((conf->keepalive_tx_tmr - MIN_Tx_KPALV_TIMER)
-				>= 0) ?
-	   			min_t(unsigned int, conf->keepalive_tx_tmr,MAX_Tx_KPALV_TIMER) :
-				DEFAULT_Tx_KPALV_TIMER;
-
-			card->u.c.kpalv_rx =
-		   		((conf->keepalive_rx_tmr - MIN_Rx_KPALV_TIMER)
-				>= 0) ?
-	   			min_t(unsigned int, conf->keepalive_rx_tmr,MAX_Rx_KPALV_TIMER) :
-				DEFAULT_Rx_KPALV_TIMER;
-
-			card->u.c.kpalv_err =
-		   		((conf->keepalive_err_margin-MIN_KPALV_ERR_TOL)
-				>= 0) ?
-	   			min_t(unsigned int, conf->keepalive_err_margin,
-				MAX_KPALV_ERR_TOL) : 
-	   			DEFAULT_KPALV_ERR_TOL;
-		}
-
-		/* Setup slarp timer to control delay between slarps */
-		card->u.c.slarp_timer = 
-			((conf->slarp_timer - MIN_SLARP_REQ_TIMER) >= 0) ?
-			min_t(unsigned int, conf->slarp_timer, MAX_SLARP_REQ_TIMER) :
-			DEFAULT_SLARP_REQ_TIMER;
-
-		if (conf->hdlc_streaming == WANOPT_YES) {
-			printk(KERN_INFO "%s: Enabling HDLC STREAMING Mode\n",
-				wandev->name);
-			card->u.c.protocol_options = HDLC_STREAMING_MODE;
-		}
-
-		if ((chdlc_priv_area->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){
-			printk(KERN_INFO 
-				"%s: Enabling, true interface type encoding.\n",
-				card->devname);
-		}
-		
-        	/* Setup wanpipe as a router (WANPIPE) or as an API */
-		if( strcmp(conf->usedby, "WANPIPE") == 0) {
-
-			printk(KERN_INFO "%s: Running in WANPIPE mode!\n",
-				wandev->name);
-			card->u.c.usedby = WANPIPE;
-
-			/* Option to bring down the interface when 
-        		 * the link goes down */
-			if (conf->if_down){
-				set_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down);
-				printk(KERN_INFO 
-				 "%s: Dynamic interface configuration enabled\n",
-				   card->devname);
-			} 
-
-		} else if( strcmp(conf->usedby, "API") == 0) {
-			card->u.c.usedby = API;
-			printk(KERN_INFO "%s: Running in API mode !\n",
-				wandev->name);
-		}
-	}
-
-	/* Tells us that if this interface is a
-         * gateway or not */
-	if ((chdlc_priv_area->gateway = conf->gateway) == WANOPT_YES){
-		printk(KERN_INFO "%s: Interface %s is set as a gateway.\n",
-			card->devname,card->u.c.if_name);
-	}
-
-	/* Get Multicast Information */
-	chdlc_priv_area->mc = conf->mc;
-
-	/* prepare network device data space for registration */
-	strcpy(dev->name,card->u.c.if_name);
-
-	dev->init = &if_init;
-	dev->priv = chdlc_priv_area;
-
-	/* Initialize the polling work routine */
-	INIT_WORK(&chdlc_priv_area->poll_work, (void*)(void*)chdlc_poll, dev);
-
-	/* Initialize the polling delay timer */
-	init_timer(&chdlc_priv_area->poll_delay_timer);
-	chdlc_priv_area->poll_delay_timer.data = (unsigned long)dev;
-	chdlc_priv_area->poll_delay_timer.function = chdlc_poll_delay;
-	
-	printk(KERN_INFO "\n");
-
-	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)
-{
-	chdlc_private_area_t* chdlc_priv_area = dev->priv;
-	sdla_t* card = chdlc_priv_area->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->flags		|= IFF_POINTOPOINT;
-	dev->flags		|= IFF_NOARP;
-
-	/* Enable Mulitcasting if user selected */
-	if (chdlc_priv_area->mc == WANOPT_YES){
-		dev->flags 	|= IFF_MULTICAST;
-	}
-	
-	if (chdlc_priv_area->true_if_encoding){
-		dev->type	= ARPHRD_HDLC; /* This breaks the tcpdump */
-	}else{
-		dev->type	= ARPHRD_PPP;
-	}
-	
-	dev->mtu		= card->wandev.mtu;
-	/* for API usage, add the API header size to the requested MTU size */
-	if(card->u.c.usedby == API) {
-		dev->mtu += sizeof(api_tx_hdr_t);
-	}
- 
-	dev->hard_header_len	= CHDLC_HDR_LEN;
-
-	/* Initialize hardware parameters */
-	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 transmit buffer queue length 
-	 * If too low packets will not be retransmitted 
-         * by stack.
-	 */
-        dev->tx_queue_len = 100;
-	SET_MODULE_OWNER(dev);
-   
-	return 0;
-}
-
-/*============================================================================
- * Open network interface.
- * o 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)
-{
-	chdlc_private_area_t* chdlc_priv_area = dev->priv;
-	sdla_t* card = chdlc_priv_area->card;
-	struct timeval tv;
-	int err = 0;
-
-	/* Only one open per interface is allowed */
-
-	if (netif_running(dev))
-		return -EBUSY;
-
-	/* Initialize the work queue entry */
-	chdlc_priv_area->tq_working=0;
-
-	INIT_WORK(&chdlc_priv_area->common.wanpipe_work,
-			(void *)(void *)chdlc_work, dev);
-
-	/* Allocate and initialize BH circular buffer */
-	/* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */
-	chdlc_priv_area->bh_head = kmalloc((sizeof(bh_data_t)*(MAX_BH_BUFF+1)),GFP_ATOMIC);
-	memset(chdlc_priv_area->bh_head,0,(sizeof(bh_data_t)*(MAX_BH_BUFF+1)));
-	atomic_set(&chdlc_priv_area->bh_buff_used, 0);
- 
-	do_gettimeofday(&tv);
-	chdlc_priv_area->router_start_time = tv.tv_sec;
-
-	netif_start_queue(dev);
-
-	wanpipe_open(card);
-
-	/* TTY is configured during wanpipe_set_termios
-	 * call, not here */
-	if (card->tty_opt)
-		return err;
-	
-	set_bit(0,&chdlc_priv_area->config_chdlc);
-	chdlc_priv_area->config_chdlc_timeout=jiffies;
-
-	/* Start the CHDLC configuration after 1sec delay.
-	 * This will give the interface initilization time
-	 * to finish its configuration */
-	mod_timer(&chdlc_priv_area->poll_delay_timer, jiffies + HZ);
-	return err;
-}
-
-/*============================================================================
- * Close network interface.
- * o if this is the last close, then disable communications and interrupts.
- * o reset flags.
- */
-static int if_close(struct net_device* dev)
-{
-	chdlc_private_area_t* chdlc_priv_area = dev->priv;
-	sdla_t* card = chdlc_priv_area->card;
-
-	if (chdlc_priv_area->bh_head){
-		int i;
-		struct sk_buff *skb;
-	
-		for (i=0; i<(MAX_BH_BUFF+1); i++){
-			skb = ((bh_data_t *)&chdlc_priv_area->bh_head[i])->skb;
-			if (skb != NULL){
-                		dev_kfree_skb_any(skb);
-			}
-		}
-		kfree(chdlc_priv_area->bh_head);
-		chdlc_priv_area->bh_head=NULL;
-	}
-
-	netif_stop_queue(dev);
-	wanpipe_close(card);
-	del_timer(&chdlc_priv_area->poll_delay_timer);
-	return 0;
-}
-
-static void disable_comm (sdla_t *card)
-{
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-	
-	if (card->u.c.comm_enabled){
-		chdlc_disable_comm_shutdown (card);
-	}else{
-		flags->interrupt_info_struct.interrupt_permission = 0;	
-	}
-
-	if (!tty_init_cnt)
-		return;
-
-	if (card->tty_opt){
-		struct serial_state * state;
-		if (!(--tty_init_cnt)){
-			int e1;
-			serial_driver.refcount=0;
-			
-			if ((e1 = tty_unregister_driver(&serial_driver)))
-				printk("SERIAL: failed to unregister serial driver (%d)\n",
-				       e1);
-			printk(KERN_INFO "%s: Unregistering TTY Driver, Major %i\n",
-					card->devname,WAN_TTY_MAJOR);
-		}
-		card->tty=NULL;
-		tty_card_map[card->tty_minor]=NULL;
-		state = &rs_table[card->tty_minor];
-		memset(state, 0, sizeof(*state));
-	}
-	return;
-}
-
-
-/*============================================================================
- * Build media header.
- *
- * The trick here is to put packet type (Ethertype) into 'protocol' field of
- * the socket buffer, so that we don't forget it.  If packet type is not
- * supported, set skb->protocol to 0 and discard packet later.
- *
- * Return:	media header length.
- */
-static int if_header(struct sk_buff* skb, struct net_device* dev,
-		     unsigned short type, void* daddr, void* saddr,
-		     unsigned len)
-{
-	skb->protocol = htons(type);
-
-	return CHDLC_HDR_LEN;
-}
-
-
-/*============================================================================
- * Handle transmit timeout event from netif watchdog
- */
-static void if_tx_timeout(struct net_device *dev)
-{
-    	chdlc_private_area_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.
-	 */
-
-	++card->wandev.stats.collisions;
-
-	printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
-	netif_wake_queue (dev);
-}
-
-
-
-/*============================================================================
- * Re-build media header.
- *
- * Return:	1	physical address resolved.
- *		0	physical address not resolved
- */
-static int if_rebuild_hdr (struct sk_buff *skb)
-{
-	return 1;
-}
-
-
-/*============================================================================
- * 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 check link state. If link is not up, then drop the packet.
- * o execute adapter send command.
- * o free socket buffer
- *
- * Return:	0	complete (socket buffer must be freed)
- *		non-0	packet may be re-transmitted (tbusy must be set)
- *
- * Notes:
- * 1. This routine is called either by the protocol stack or by the "net
- *    bottom half" (with interrupts enabled).
- * 2. Setting tbusy flag will inhibit further transmit requests from the
- *    protocol stack and can be used for flow control with protocol layer.
- */
-static int if_send(struct sk_buff* skb, struct net_device* dev)
-{
-	chdlc_private_area_t *chdlc_priv_area = dev->priv;
-	sdla_t *card = chdlc_priv_area->card;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-	INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
-	int udp_type = 0;
-	unsigned long smp_flags;
-	int err=0;
-
-	netif_stop_queue(dev);
-	
-	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) != htons(PVC_PROT)){
-
-		/* 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;
-			}
-			netif_start_queue(dev);
-			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)){
-			++card->wandev.stats.tx_dropped;
-			dev_kfree_skb_any(skb);
-			netif_start_queue(dev);
-			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(SEND_CRIT, (void*)&card->wandev.critical)) {
-	
-		printk(KERN_INFO "%s: Critical in if_send: %lx\n",
-					card->wandev.name,card->wandev.critical);
-                ++card->wandev.stats.tx_dropped;
-		netif_start_queue(dev);
-		goto if_send_exit_crit;
-	}
-
-	if(card->u.c.state != WAN_CONNECTED){
-       		++card->wandev.stats.tx_dropped;
-		netif_start_queue(dev);
-		
-	}else if(!skb->protocol){
-        	++card->wandev.stats.tx_errors;
-		netif_start_queue(dev);
-		
-	}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;
-
-			/* discard the frame if we are configured for */
-			/* 'receive only' mode or if there is no data */
-			if (card->u.c.receive_only ||
-				(len <= sizeof(api_tx_hdr_t))) {
-				
-				++card->wandev.stats.tx_dropped;
-				netif_start_queue(dev);
-				goto if_send_exit_crit;
-			}
-				
-			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);
-		}else{
-			++card->wandev.stats.tx_packets;
-                        card->wandev.stats.tx_bytes += len;
-			
-			netif_start_queue(dev);
-			
-		 	dev->trans_start = jiffies;
-		}	
-	}
-
-if_send_exit_crit:
-	
-	if (!(err=netif_queue_stopped(dev))) {
-		dev_kfree_skb_any(skb);
-	}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, struct net_device* dev,
-				struct sk_buff *skb)
-{
-	u32 src_ip_addr;
-        u32 broadcast_ip_addr = 0;
-        struct in_device *in_dev;
-
-        /* read the IP source address from the outgoing packet */
-        src_ip_addr = *(u32 *)(skb->data + 12);
-
-	/* read the IP broadcast address for the device */
-        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;
-        }
- 
-        /* 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.
- */
-static struct net_device_stats* if_stats(struct net_device* 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; 
-}
-
-
-/****** 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)
-{
-	unsigned cmd = mb->command;
-
-	switch (err) {
-
-	case CMD_TIMEOUT:
-		printk(KERN_INFO "%s: command 0x%02X timed out!\n",
-			card->devname, cmd);
-		break;
-
-	case S514_BOTH_PORTS_SAME_CLK_MODE:
-		if(cmd == SET_CHDLC_CONFIGURATION) {
-			printk(KERN_INFO
-			 "%s: Configure both ports for the same clock source\n",
-				card->devname);
-			break;
-		}
-
-	default:
-		printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
-			card->devname, cmd, err);
-	}
-
-	return 0;
-}
-
-
-/********** Bottom Half Handlers ********************************************/
-
-/* NOTE: There is no API, BH support for Kernels lower than 2.2.X.
- *       DO NOT INSERT ANY CODE HERE, NOTICE THE 
- *       PREPROCESSOR STATEMENT ABOVE, UNLESS YOU KNOW WHAT YOU ARE
- *       DOING */
-
-static void chdlc_work(struct net_device * dev)
-{
-	chdlc_private_area_t* chan = dev->priv;
-	sdla_t *card = chan->card;
-	struct sk_buff *skb;
-
-	if (atomic_read(&chan->bh_buff_used) == 0){
-		clear_bit(0, &chan->tq_working);
-		return;
-	}
-
-	while (atomic_read(&chan->bh_buff_used)){
-
-		skb  = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb;
-
-		if (skb != NULL){
-
-			if (chan->common.sk == NULL || chan->common.func == NULL){
-				++card->wandev.stats.rx_dropped;
-				dev_kfree_skb_any(skb);
-				chdlc_work_cleanup(dev);
-				continue;
-			}
-
-			if (chan->common.func(skb,dev,chan->common.sk) != 0){
-				/* Sock full cannot send, queue us for another
-                                 * try */
-				atomic_set(&chan->common.receive_block,1);
-				return;
-			}else{
-				chdlc_work_cleanup(dev);
-			}
-		}else{
-			chdlc_work_cleanup(dev);
-		}
-	}	
-	clear_bit(0, &chan->tq_working);
-
-	return;
-}
-
-static int chdlc_work_cleanup(struct net_device *dev)
-{
-	chdlc_private_area_t* chan = dev->priv;
-
-	((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL;
-
-	if (chan->bh_read == MAX_BH_BUFF){
-		chan->bh_read=0;
-	}else{
-		++chan->bh_read;	
-	}
-
-	atomic_dec(&chan->bh_buff_used);
-	return 0;
-}
-
-
-
-static int bh_enqueue(struct net_device *dev, struct sk_buff *skb)
-{
-	/* Check for full */
-	chdlc_private_area_t* chan = dev->priv;
-	sdla_t *card = chan->card;
-
-	if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){
-		++card->wandev.stats.rx_dropped;
-		dev_kfree_skb_any(skb);
-		return 1; 
-	}
-
-	((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb;
-
-	if (chan->bh_write == MAX_BH_BUFF){
-		chan->bh_write=0;
-	}else{
-		++chan->bh_write;
-	}
-
-	atomic_inc(&chan->bh_buff_used);
-
-	return 0;
-}
-
-/* END OF API BH Support */
-
-
-/****** Interrupt Handlers **************************************************/
-
-/*============================================================================
- * Cisco HDLC interrupt service routine.
- */
-static void wpc_isr (sdla_t* card)
-{
-	struct net_device* dev;
-	SHARED_MEMORY_INFO_STRUCT* flags = NULL;
-	int i;
-	sdla_t *my_card;
-
-
-	/* Check for which port the interrupt has been generated
-	 * Since Secondary Port is piggybacking on the Primary
-         * the check must be done here. 
-	 */
-
-	flags = card->u.c.flags;
-	if (!flags->interrupt_info_struct.interrupt_type){
-		/* Check for a second port (piggybacking) */
-		if ((my_card = card->next)){
-			flags = my_card->u.c.flags;
-			if (flags->interrupt_info_struct.interrupt_type){
-				card = my_card;
-				card->isr(card);
-				return;
-			}
-		}
-	}
-
-	flags = card->u.c.flags;
-	card->in_isr = 1;
-	dev = card->wandev.dev;
-	
-	/* If we get an interrupt with no network device, stop the interrupts
-	 * and issue an error */
-	if (!card->tty_opt && !dev && 
-	    flags->interrupt_info_struct.interrupt_type != 
-	    	COMMAND_COMPLETE_APP_INT_PEND){
-
-		goto isr_done;
-	}
-	
-	/* if critical due to peripheral operations
-	 * ie. update() or getstats() then reset the interrupt and
-	 * wait for the board to retrigger.
-	 */
-	if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
-		printk(KERN_INFO "ISR CRIT TO PERI\n");
-		goto isr_done;
-	}
-
-	/* On a 508 Card, if critical due to if_send 
-         * Major Error !!! */
-	if(card->hw.type != SDLA_S514) {
-		if(test_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
-			printk(KERN_INFO "%s: Critical while in ISR: %lx\n",
-				card->devname, card->wandev.critical);
-			card->in_isr = 0;
-			flags->interrupt_info_struct.interrupt_type = 0;
-			return;
-		}
-	}
-
-	switch(flags->interrupt_info_struct.interrupt_type) {
-
-	case RX_APP_INT_PEND:	/* 0x01: receive interrupt */
-		rx_intr(card);
-		break;
-
-	case TX_APP_INT_PEND:	/* 0x02: transmit interrupt */
-		flags->interrupt_info_struct.interrupt_permission &=
-			 ~APP_INT_ON_TX_FRAME;
-
-		if (card->tty_opt){
-			wanpipe_tty_trigger_poll(card);
-			break;
-		}
-
-		if (dev && netif_queue_stopped(dev)){
-			if (card->u.c.usedby == API){
-				netif_start_queue(dev);
-				wakeup_sk_bh(dev);
-			}else{
-				netif_wake_queue(dev);
-			}
-		}
-		break;
-
-	case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
-		++ Intr_test_counter;
-		break;
-
-	case CHDLC_EXCEP_COND_APP_INT_PEND:	/* 0x20 */
-		process_chdlc_exception(card);
-		break;
-
-	case GLOBAL_EXCEP_COND_APP_INT_PEND:
-		process_global_exception(card);
-		break;
-
-	case TIMER_APP_INT_PEND:
-		timer_intr(card);
-		break;
-
-	default:
-		printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", 
-			card->devname,
-			flags->interrupt_info_struct.interrupt_type);
-		printk(KERN_INFO "Code name: ");
-		for(i = 0; i < 4; i ++)
-			printk(KERN_INFO "%c",
-				flags->global_info_struct.codename[i]); 
-		printk(KERN_INFO "\nCode version: ");
-	 	for(i = 0; i < 4; i ++)
-			printk(KERN_INFO "%c", 
-				flags->global_info_struct.codeversion[i]); 
-		printk(KERN_INFO "\n");	
-		break;
-	}
-
-isr_done:
-
-	card->in_isr = 0;
-	flags->interrupt_info_struct.interrupt_type = 0;
-	return;
-}
-
-/*============================================================================
- * Receive interrupt handler.
- */
-static void rx_intr (sdla_t* card)
-{
-	struct net_device *dev;
-	chdlc_private_area_t *chdlc_priv_area;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-	CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
-	struct sk_buff *skb;
-	unsigned len;
-	unsigned addr = rxbuf->ptr_data_bfr;
-	void *buf;
-	int i,udp_type;
-
-	if (rxbuf->opp_flag != 0x01) {
-		printk(KERN_INFO 
-			"%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", 
-			card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
-                printk(KERN_INFO "Code name: ");
-                for(i = 0; i < 4; i ++)
-                        printk(KERN_INFO "%c",
-                                flags->global_info_struct.codename[i]);
-                printk(KERN_INFO "\nCode version: ");
-                for(i = 0; i < 4; i ++)
-                        printk(KERN_INFO "%c",
-                                flags->global_info_struct.codeversion[i]);
-                printk(KERN_INFO "\n");
-
-
-		/* Bug Fix: Mar 6 2000
-                 * If we get a corrupted mailbox, it measn that driver 
-                 * is out of sync with the firmware. There is no recovery.
-                 * If we don't turn off all interrupts for this card
-                 * the machine will crash. 
-                 */
-		printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
-		printk(KERN_INFO "Please contact Sangoma Technologies !\n");
-		chdlc_set_intr_mode(card,0);	
-		return;
-	}
-
-	len  = rxbuf->frame_length;
-
-	if (card->tty_opt){
-
-		if (rxbuf->error_flag){	
-			goto rx_exit;
-		}
-
-		if (len <= CRC_LENGTH){
-			goto rx_exit;
-		}
-		
-		if (!card->u.c.async_mode){
-			len -= CRC_LENGTH;
-		}
-
-		wanpipe_tty_receive(card,addr,len);
-		goto rx_exit;
-	}
-
-	dev = card->wandev.dev;
-
-	if (!dev){
-		goto rx_exit;
-	}
-
-	if (!netif_running(dev))
-		goto rx_exit;
-
-	chdlc_priv_area = dev->priv;
-
-	
-	/* Allocate socket buffer */
-	skb = dev_alloc_skb(len);
-
-	if (skb == NULL) {
-		printk(KERN_INFO "%s: no socket buffers available!\n",
-					card->devname);
-		++card->wandev.stats.rx_dropped;
-		goto rx_exit;
-	}
-
-	/* Copy data to the socket buffer */
-	if((addr + len) > card->u.c.rx_top + 1) {
-		unsigned tmp = card->u.c.rx_top - addr + 1;
-		buf = skb_put(skb, tmp);
-		sdla_peek(&card->hw, addr, buf, tmp);
-		addr = card->u.c.rx_base;
-		len -= tmp;
-	}
-		
-	buf = skb_put(skb, len);
-	sdla_peek(&card->hw, addr, buf, len);
-
-	skb->protocol = htons(ETH_P_IP);
-
-	card->wandev.stats.rx_packets ++;
-	card->wandev.stats.rx_bytes += skb->len;
-	udp_type = udp_pkt_type( skb, card );
-
-	if(udp_type == UDP_CPIPE_TYPE) {
-		if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
-   				      card, skb, dev, chdlc_priv_area)) {
-     		        flags->interrupt_info_struct.
-						interrupt_permission |= 
-							APP_INT_ON_TIMER; 
-		}
-	} else if(card->u.c.usedby == API) {
-
-		api_rx_hdr_t* api_rx_hdr;
-       		skb_push(skb, sizeof(api_rx_hdr_t));
-                api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00];
-		api_rx_hdr->error_flag = rxbuf->error_flag;
-     		api_rx_hdr->time_stamp = rxbuf->time_stamp;
-
-                skb->protocol = htons(PVC_PROT);
-     		skb->mac.raw  = skb->data;
-		skb->dev      = dev;
-               	skb->pkt_type = WAN_PACKET_DATA;
-
-		bh_enqueue(dev, skb);
-
-		if (!test_and_set_bit(0,&chdlc_priv_area->tq_working))
-			wanpipe_queue_work(&chdlc_priv_area->common.wanpipe_work);
-	}else{
-		/* FIXME: we should check to see if the received packet is a 
-                          multicast packet so that we can increment the multicast 
-                          statistic
-                          ++ chdlc_priv_area->if_stats.multicast;
-		*/
-               	/* Pass it up the protocol stack */
-	
-                skb->dev = dev;
-                skb->mac.raw  = skb->data;
-                netif_rx(skb);
-                dev->last_rx = jiffies;
-	}
-
-rx_exit:
-	/* Release buffer element and calculate a pointer to the next one */
-	rxbuf->opp_flag = 0x00;
-	card->u.c.rxmb = ++ rxbuf;
-	if((void*)rxbuf > card->u.c.rxbuf_last){
-		card->u.c.rxmb = card->u.c.rxbuf_base;
-	}
-}
-
-/*============================================================================
- * Timer interrupt handler.
- * The timer interrupt is used for two purposes:
- *    1) Processing udp calls from 'cpipemon'.
- *    2) Reading board-level statistics for updating the proc file system.
- */
-void timer_intr(sdla_t *card)
-{
-        struct net_device* dev;
-        chdlc_private_area_t* chdlc_priv_area = NULL;
-        SHARED_MEMORY_INFO_STRUCT* flags = NULL;
-
-        if ((dev = card->wandev.dev)==NULL){
-		flags = card->u.c.flags;
-                flags->interrupt_info_struct.interrupt_permission &=
-                        ~APP_INT_ON_TIMER;
-		return;
-	}
-	
-        chdlc_priv_area = dev->priv;
-
-	if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) {
-		if (!config_chdlc(card)){
-			chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
-		}
-	}
-
-	/* process a udp call if pending */
-       	if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
-               	process_udp_mgmt_pkt(card, dev,
-                       chdlc_priv_area);
-		chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
-        }
-
-	/* read the communications statistics if required */
-	if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
-		update_comms_stats(card, chdlc_priv_area);
-                if(!(-- chdlc_priv_area->update_comms_stats)) {
-			chdlc_priv_area->timer_int_enabled &= 
-				~TMR_INT_ENABLED_UPDATE;
-		}
-        }
-
-	/* only disable the timer interrupt if there are no udp or statistic */
-	/* updates pending */
-        if(!chdlc_priv_area->timer_int_enabled) {
-                flags = card->u.c.flags;
-                flags->interrupt_info_struct.interrupt_permission &=
-                        ~APP_INT_ON_TIMER;
-        }
-}
-
-/*------------------------------------------------------------------------------
-  Miscellaneous Functions
-	- set_chdlc_config() used to set configuration options on the board
-------------------------------------------------------------------------------*/
-
-static int set_chdlc_config(sdla_t* card)
-{
-	CHDLC_CONFIGURATION_STRUCT cfg;
-
-	memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
-
-	if(card->wandev.clocking){
-		cfg.baud_rate = card->wandev.bps;
-	}
-		
-	cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
-		INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
-
-	cfg.modem_config_options	= 0;
-	cfg.modem_status_timer		= 100;
-
-	cfg.CHDLC_protocol_options	= card->u.c.protocol_options;
-
-	if (card->tty_opt){
-		cfg.CHDLC_API_options	= DISCARD_RX_ERROR_FRAMES;
-	}
-	
-	cfg.percent_data_buffer_for_Tx  = (card->u.c.receive_only) ? 0 : 50;
-	cfg.CHDLC_statistics_options	= (CHDLC_TX_DATA_BYTE_COUNT_STAT |
-		CHDLC_RX_DATA_BYTE_COUNT_STAT);
-	
-	if (card->tty_opt){
-		card->wandev.mtu = TTY_CHDLC_MAX_MTU;
-	}
-	cfg.max_CHDLC_data_field_length	= card->wandev.mtu;
-	cfg.transmit_keepalive_timer	= card->u.c.kpalv_tx;
-	cfg.receive_keepalive_timer	= card->u.c.kpalv_rx;
-	cfg.keepalive_error_tolerance	= card->u.c.kpalv_err;
-	cfg.SLARP_request_timer		= card->u.c.slarp_timer;
-
-	if (cfg.SLARP_request_timer) {
-		cfg.IP_address		= 0;
-		cfg.IP_netmask		= 0;
-		
-	}else if (card->wandev.dev){
-		struct net_device *dev = card->wandev.dev;
-		chdlc_private_area_t *chdlc_priv_area = dev->priv;
-		
-                struct in_device *in_dev = dev->ip_ptr;
-
-		if(in_dev != NULL) {
-			struct in_ifaddr *ifa = in_dev->ifa_list;
-
-			if (ifa != NULL ) {
-				cfg.IP_address	= ntohl(ifa->ifa_local);
-				cfg.IP_netmask	= ntohl(ifa->ifa_mask); 
-				chdlc_priv_area->IP_address = ntohl(ifa->ifa_local);
-				chdlc_priv_area->IP_netmask = ntohl(ifa->ifa_mask); 
-			}
-		}
-
-		/* FIXME: We must re-think this message in next release
-		if((cfg.IP_address & 0x000000FF) > 2) {
-			printk(KERN_WARNING "\n");
-	                printk(KERN_WARNING "  WARNING:%s configured with an\n",
-				card->devname);
-			printk(KERN_WARNING "  invalid local IP address.\n");
-                        printk(KERN_WARNING "  Slarp pragmatics will fail.\n");
-                        printk(KERN_WARNING "  IP address should be of the\n");
-			printk(KERN_WARNING "  format A.B.C.1 or A.B.C.2.\n");
-		}
-		*/		
-	}
-	
-	return chdlc_configure(card, &cfg);
-}
-
-
-/*-----------------------------------------------------------------------------
-   set_asy_config() used to set asynchronous configuration options on the board
-------------------------------------------------------------------------------*/
-
-static int set_asy_config(sdla_t* card)
-{
-
-        ASY_CONFIGURATION_STRUCT cfg;
- 	CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
-	int err;
-
-	memset(&cfg, 0, sizeof(ASY_CONFIGURATION_STRUCT));
-
-	if(card->wandev.clocking)
-		cfg.baud_rate = card->wandev.bps;
-
-	cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
-		INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
-
-	cfg.modem_config_options	= 0;
-	cfg.asy_API_options 		= card->u.c.api_options;
-	cfg.asy_protocol_options	= card->u.c.protocol_options;
-	cfg.Tx_bits_per_char		= card->u.c.tx_bits_per_char;
-	cfg.Rx_bits_per_char		= card->u.c.rx_bits_per_char;
-	cfg.stop_bits			= card->u.c.stop_bits;
-	cfg.parity			= card->u.c.parity;
-	cfg.break_timer			= card->u.c.break_timer;
-	cfg.asy_Rx_inter_char_timer	= card->u.c.inter_char_timer; 
-	cfg.asy_Rx_complete_length	= card->u.c.rx_complete_length; 
-	cfg.XON_char			= card->u.c.xon_char;
-	cfg.XOFF_char			= card->u.c.xoff_char;
-	cfg.asy_statistics_options	= (CHDLC_TX_DATA_BYTE_COUNT_STAT |
-		CHDLC_RX_DATA_BYTE_COUNT_STAT);
-
-	mailbox->buffer_length = sizeof(ASY_CONFIGURATION_STRUCT);
-	memcpy(mailbox->data, &cfg, mailbox->buffer_length);
-	mailbox->command = SET_ASY_CONFIGURATION;
-	err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
-	if (err != COMMAND_OK) 
-		chdlc_error (card, err, mailbox);
-	return err;
-}
-
-/*============================================================================
- * Enable asynchronous communications.
- */
-
-static int asy_comm_enable (sdla_t* card)
-{
-
-	int err;
-	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
-
-	mb->buffer_length = 0;
-	mb->command = ENABLE_ASY_COMMUNICATIONS;
-	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-	if (err != COMMAND_OK && card->wandev.dev)
-		chdlc_error(card, err, mb);
-	
-	if (!err)
-		card->u.c.comm_enabled = 1;
-
-	return err;
-}
-
-/*============================================================================
- * Process global exception condition
- */
-static int process_global_exception(sdla_t *card)
-{
-	CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
-	int err;
-
-	mbox->buffer_length = 0;
-	mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
-	err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
-
-	if(err != CMD_TIMEOUT ){
-	
-		switch(mbox->return_code) {
-         
-	      	case EXCEP_MODEM_STATUS_CHANGE:
-
-			printk(KERN_INFO "%s: Modem status change\n",
-				card->devname);
-
-			switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
-				case (DCD_HIGH):
-					printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname);
-					break;
-				case (CTS_HIGH):
-                                        printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname); 
-					break;
-                                case ((DCD_HIGH | CTS_HIGH)):
-                                        printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname);
-                                        break;
-				default:
-                                        printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname);
-                                        break;
-			}
-			break;
-
-                case EXCEP_TRC_DISABLED:
-                        printk(KERN_INFO "%s: Line trace disabled\n",
-				card->devname);
-                        break;
-
-		case EXCEP_IRQ_TIMEOUT:
-			printk(KERN_INFO "%s: IRQ timeout occurred\n",
-				card->devname); 
-			break;
-
-		case 0x17:
-			if (card->tty_opt){
-				if (card->tty && card->tty_open){ 
-					printk(KERN_INFO 
-						"%s: Modem Hangup Exception: Hanging Up!\n",
-						card->devname);
-					tty_hangup(card->tty);
-				}
-				break;
-			}
-
-			/* If TTY is not used just drop throught */
-			
-                default:
-                        printk(KERN_INFO "%s: Global exception %x\n",
-				card->devname, mbox->return_code);
-                        break;
-                }
-	}
-	return 0;
-}
-
-
-/*============================================================================
- * Process chdlc exception condition
- */
-static int process_chdlc_exception(sdla_t *card)
-{
-	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
-	int err;
-
-	mb->buffer_length = 0;
-	mb->command = READ_CHDLC_EXCEPTION_CONDITION;
-	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-	if(err != CMD_TIMEOUT) {
-	
-		switch (err) {
-
-		case EXCEP_LINK_ACTIVE:
-			port_set_state(card, WAN_CONNECTED);
-			trigger_chdlc_poll(card->wandev.dev);
-			break;
-
-		case EXCEP_LINK_INACTIVE_MODEM:
-			port_set_state(card, WAN_DISCONNECTED);
-			unconfigure_ip(card);
-			trigger_chdlc_poll(card->wandev.dev);
-			break;
-
-		case EXCEP_LINK_INACTIVE_KPALV:
-			port_set_state(card, WAN_DISCONNECTED);
-			printk(KERN_INFO "%s: Keepalive timer expired.\n",
-				 		card->devname);
-			unconfigure_ip(card);
-			trigger_chdlc_poll(card->wandev.dev);
-			break;
-
-		case EXCEP_IP_ADDRESS_DISCOVERED:
-			if (configure_ip(card)) 
-				return -1;
-			break;
-
-		case EXCEP_LOOPBACK_CONDITION:
-			printk(KERN_INFO "%s: Loopback Condition Detected.\n",
-						card->devname);
-			break;
-
-		case NO_CHDLC_EXCEP_COND_TO_REPORT:
-			printk(KERN_INFO "%s: No exceptions reported.\n",
-						card->devname);
-			break;
-		}
-
-	}
-	return 0;
-}
-
-
-/*============================================================================
- * Configure IP from SLARP negotiation
- * This adds dynamic routes when SLARP has provided valid addresses
- */
-
-static int configure_ip (sdla_t* card)
-{
-	struct net_device *dev = card->wandev.dev;
-        chdlc_private_area_t *chdlc_priv_area;
-        char err;
-
-	if (!dev)
-		return 0;
-
-	chdlc_priv_area = dev->priv;
-	
-	
-        /* set to discover */
-        if(card->u.c.slarp_timer != 0x00) {
-		CHDLC_MAILBOX_STRUCT* mb = card->mbox;
-		CHDLC_CONFIGURATION_STRUCT *cfg;
-
-     		mb->buffer_length = 0;
-		mb->command = READ_CHDLC_CONFIGURATION;
-		err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-	
-		if(err != COMMAND_OK) {
-			chdlc_error(card,err,mb);
-			return -1;
-		}
-
-		cfg = (CHDLC_CONFIGURATION_STRUCT *)mb->data;
-                chdlc_priv_area->IP_address = cfg->IP_address;
-                chdlc_priv_area->IP_netmask = cfg->IP_netmask;
-
-		/* Set flag to add route */
-		chdlc_priv_area->route_status = ADD_ROUTE;
-
-		/* The idea here is to add the route in the poll routine.
-	   	This way, we aren't in interrupt context when adding routes */
-		trigger_chdlc_poll(dev);
-        }
-
-	return 0;
-}
-
-
-/*============================================================================
- * Un-Configure IP negotiated by SLARP
- * This removes dynamic routes when the link becomes inactive.
- */
-
-static int unconfigure_ip (sdla_t* card)
-{
-	struct net_device *dev = card->wandev.dev;
-	chdlc_private_area_t *chdlc_priv_area;
-
-	if (!dev)
-		return 0;
-
-	chdlc_priv_area= dev->priv;
-	
-	if (chdlc_priv_area->route_status == ROUTE_ADDED) {
-
-		/* Note: If this function is called, the 
-                 * port state has been DISCONNECTED.  This state
-                 * change will trigger a poll_disconnected 
-                 * function, that will check for this condition. 
-		 */
-		chdlc_priv_area->route_status = REMOVE_ROUTE;
-
-	}
-	return 0;
-}
-
-/*============================================================================
- * Routine to add/remove routes 
- * Called like a polling routine when Routes are flagged to be added/removed.
- */
-
-static void process_route (sdla_t *card)
-{
-        struct net_device *dev = card->wandev.dev;
-        unsigned char port_num;
-        chdlc_private_area_t *chdlc_priv_area = NULL;
-	u32 local_IP_addr = 0;
-	u32 remote_IP_addr = 0;
-	u32 IP_netmask, IP_addr;
-        int err = 0;
-	struct in_device *in_dev;
-	mm_segment_t fs;
-	struct ifreq if_info;
-        struct sockaddr_in *if_data1, *if_data2;
-	
-        chdlc_priv_area = dev->priv;
-        port_num = card->u.c.comm_port;
-
-	/* Bug Fix Mar 16 2000
-	 * AND the IP address to the Mask before checking
-         * the last two bits. */
-
-	if((chdlc_priv_area->route_status == ADD_ROUTE) &&
-		((chdlc_priv_area->IP_address & ~chdlc_priv_area->IP_netmask) > 2)) {
-
-		printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname);
-
-                if(card->u.c.slarp_timer) {
-			u32 addr_net = htonl(chdlc_priv_area->IP_address);
-
-			printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u received\n",
-				card->devname,
-			       NIPQUAD(addr_net));
-                        printk(KERN_INFO "%s: from remote station.\n",
-				card->devname);
-
-                }else{ 
-			u32 addr_net = htonl(chdlc_priv_area->IP_address);
-
-                        printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u issued\n",
-			       card->devname,
-			       NIPQUAD(addr_net));
-                        printk(KERN_INFO "%s: to remote station. Local\n",
-				card->devname);
-			printk(KERN_INFO "%s: IP address must be A.B.C.1\n",
-				card->devname);
-			printk(KERN_INFO "%s: or A.B.C.2.\n",card->devname);
-		}
-
-		/* remove the route due to the IP address error condition */
-		chdlc_priv_area->route_status = REMOVE_ROUTE;
-		err = 1;
-   	}
-
-	/* If we are removing a route with bad IP addressing, then use the */
-	/* locally configured IP addresses */
-        if((chdlc_priv_area->route_status == REMOVE_ROUTE) && err) {
-
- 	        /* do not remove a bad route that has already been removed */
-        	if(chdlc_priv_area->route_removed) {
-	                return;
-        	}
-
-                in_dev = dev->ip_ptr;
-
-                if(in_dev != NULL) {
-                        struct in_ifaddr *ifa = in_dev->ifa_list;
-                        if (ifa != NULL ) {
-                                local_IP_addr = ifa->ifa_local;
-                                IP_netmask  = ifa->ifa_mask;
-                        }
-                }
-	}else{ 
-       		/* According to Cisco HDLC, if the point-to-point address is
-		   A.B.C.1, then we are the opposite (A.B.C.2), and vice-versa.
-		*/
-		IP_netmask = ntohl(chdlc_priv_area->IP_netmask);
-	        remote_IP_addr = ntohl(chdlc_priv_area->IP_address);
-	
-
-		/* If Netmask is 255.255.255.255 the local address
-                 * calculation will fail. Default it back to 255.255.255.0 */
-		if (IP_netmask == 0xffffffff)
-			IP_netmask &= 0x00ffffff;
-
-		/* Bug Fix Mar 16 2000
-		 * AND the Remote IP address with IP netmask, instead
-                 * of static netmask of 255.255.255.0 */
-        	local_IP_addr = (remote_IP_addr & IP_netmask) +
-                	(~remote_IP_addr & ntohl(0x0003));
-
-	        if(!card->u.c.slarp_timer) {
-			IP_addr = local_IP_addr;
-			local_IP_addr = remote_IP_addr;
-			remote_IP_addr = IP_addr;
-       		}
-	}
-
-        fs = get_fs();                  /* Save file system  */
-        set_fs(get_ds());               /* Get user space block */
-
-        /* Setup a structure for adding/removing routes */
-        memset(&if_info, 0, sizeof(if_info));
-        strcpy(if_info.ifr_name, dev->name);
-
-	switch (chdlc_priv_area->route_status) {
-
-	case ADD_ROUTE:
-
-		if(!card->u.c.slarp_timer) {
-			if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
-			if_data2->sin_addr.s_addr = remote_IP_addr;
-			if_data2->sin_family = AF_INET;
-			err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
-		} else { 
-			if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
-			if_data1->sin_addr.s_addr = local_IP_addr;
-			if_data1->sin_family = AF_INET;
-			if(!(err = devinet_ioctl(SIOCSIFADDR, &if_info))){
-				if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
-				if_data2->sin_addr.s_addr = remote_IP_addr;
-				if_data2->sin_family = AF_INET;
-				err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
-			}
-		}
-
-               if(err) {
-			printk(KERN_INFO "%s: Add route %u.%u.%u.%u failed (%d)\n", 
-				card->devname, NIPQUAD(remote_IP_addr), err);
-		} else {
-			((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED;
-			printk(KERN_INFO "%s: Dynamic route added.\n",
-				card->devname);
-			printk(KERN_INFO "%s:    Local IP addr : %u.%u.%u.%u\n",
-				card->devname, NIPQUAD(local_IP_addr));
-			printk(KERN_INFO "%s:    Remote IP addr: %u.%u.%u.%u\n",
-				card->devname, NIPQUAD(remote_IP_addr));
-			chdlc_priv_area->route_removed = 0;
-		}
-		break;
-
-
-	case REMOVE_ROUTE:
-	
-		/* Change the local ip address of the interface to 0.
-		 * This will also delete the destination route.
-		 */
-		if(!card->u.c.slarp_timer) {
-			if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
-			if_data2->sin_addr.s_addr = 0;
-			if_data2->sin_family = AF_INET;
-			err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
-		} else {
-			if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
-			if_data1->sin_addr.s_addr = 0;
-			if_data1->sin_family = AF_INET;
-			err = devinet_ioctl(SIOCSIFADDR,&if_info);
-		
-		}
-		if(err) {
-			printk(KERN_INFO
-				"%s: Remove route %u.%u.%u.%u failed, (err %d)\n",
-					card->devname, NIPQUAD(remote_IP_addr),
-					err);
-		} else {
-			((chdlc_private_area_t *)dev->priv)->route_status =
-				NO_ROUTE;
-                        printk(KERN_INFO "%s: Dynamic route removed: %u.%u.%u.%u\n",
-                                        card->devname, NIPQUAD(local_IP_addr)); 
-			chdlc_priv_area->route_removed = 1;
-		}
-		break;
-	}
-
-        set_fs(fs);                     /* Restore file system */
-
-}
-
-
-/*=============================================================================
- * Store a UDP management packet for later processing.
- */
-
-static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
-			      struct sk_buff *skb, struct net_device* dev,
-			      chdlc_private_area_t* chdlc_priv_area)
-{
-	int udp_pkt_stored = 0;
-
-	if(!chdlc_priv_area->udp_pkt_lgth &&
-	  (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
-        	chdlc_priv_area->udp_pkt_lgth = skb->len;
-		chdlc_priv_area->udp_pkt_src = udp_pkt_src;
-       		memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
-		chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
-		udp_pkt_stored = 1;
-	}
-
-	if(udp_pkt_src == UDP_PKT_FRM_STACK){
-		dev_kfree_skb_any(skb);
-	}else{
-                dev_kfree_skb_any(skb);
-	}
-		
-	return(udp_pkt_stored);
-}
-
-
-/*=============================================================================
- * Process UDP management packet.
- */
-
-static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
-				chdlc_private_area_t* chdlc_priv_area ) 
-{
-	unsigned char *buf;
-	unsigned int frames, len;
-	struct sk_buff *new_skb;
-	unsigned short buffer_length, real_len;
-	unsigned long data_ptr;
-	unsigned data_length;
-	int udp_mgmt_req_valid = 1;
-	CHDLC_MAILBOX_STRUCT *mb = card->mbox;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-	chdlc_udp_pkt_t *chdlc_udp_pkt;
-	struct timeval tv;
-	int err;
-	char ut_char;
-
-	chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
-
-	if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
-
-		/* Only these commands are support for remote debugging.
-		 * All others are not */
-		switch(chdlc_udp_pkt->cblock.command) {
-
-			case READ_GLOBAL_STATISTICS:
-			case READ_MODEM_STATUS:  
-			case READ_CHDLC_LINK_STATUS:
-			case CPIPE_ROUTER_UP_TIME:
-			case READ_COMMS_ERROR_STATS:
-			case READ_CHDLC_OPERATIONAL_STATS:
-
-			/* These two commands are executed for
-			 * each request */
-			case READ_CHDLC_CONFIGURATION:
-			case READ_CHDLC_CODE_VERSION:
-				udp_mgmt_req_valid = 1;
-				break;
-			default:
-				udp_mgmt_req_valid = 0;
-				break;
-		} 
-	}
-	
-  	if(!udp_mgmt_req_valid) {
-
-		/* set length to 0 */
-		chdlc_udp_pkt->cblock.buffer_length = 0;
-
-    		/* set return code */
-		chdlc_udp_pkt->cblock.return_code = 0xCD;
-
-		if (net_ratelimit()){	
-			printk(KERN_INFO 
-			"%s: Warning, Illegal UDP command attempted from network: %x\n",
-			card->devname,chdlc_udp_pkt->cblock.command);
-		}
-
-   	} else {
-	   	unsigned long trace_status_cfg_addr = 0;
-		TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
-		TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
-
-		switch(chdlc_udp_pkt->cblock.command) {
-
-		case CPIPE_ENABLE_TRACING:
-		     if (!chdlc_priv_area->TracingEnabled) {
-
-			/* OPERATE_DATALINE_MONITOR */
-
-			mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
-			mb->command = SET_TRACE_CONFIGURATION;
-
-    			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
-				trace_config = TRACE_ACTIVE;
-			/* Trace delay mode is not used because it slows
-			   down transfer and results in a standoff situation
-			   when there is a lot of data */
-
-			/* Configure the Trace based on user inputs */
-			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= 
-					chdlc_udp_pkt->data[0];
-
-			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
-			   trace_deactivation_timer = 4000;
-
-
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-			if (err != COMMAND_OK) {
-				chdlc_error(card,err,mb);
-				card->TracingEnabled = 0;
-				chdlc_udp_pkt->cblock.return_code = err;
-				mb->buffer_length = 0;
-				break;
-	    		} 
-
-			/* Get the base address of the trace element list */
-			mb->buffer_length = 0;
-			mb->command = READ_TRACE_CONFIGURATION;
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-
-			if (err != COMMAND_OK) {
-				chdlc_error(card,err,mb);
-				chdlc_priv_area->TracingEnabled = 0;
-				chdlc_udp_pkt->cblock.return_code = err;
-				mb->buffer_length = 0;
-				break;
-	    		} 	
-
-	   		trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
-				mb->data) -> ptr_trace_stat_el_cfg_struct;
-
-			sdla_peek(&card->hw, trace_status_cfg_addr,
-				 &trace_cfg_struct, sizeof(trace_cfg_struct));
-		    
-			chdlc_priv_area->start_trace_addr = trace_cfg_struct.
-				base_addr_trace_status_elements;
-
-			chdlc_priv_area->number_trace_elements = 
-					trace_cfg_struct.number_trace_status_elements;
-
-			chdlc_priv_area->end_trace_addr = (unsigned long)
-					((TRACE_STATUS_ELEMENT_STRUCT *)
-					 chdlc_priv_area->start_trace_addr + 
-					 (chdlc_priv_area->number_trace_elements - 1));
-
-			chdlc_priv_area->base_addr_trace_buffer = 
-					trace_cfg_struct.base_addr_trace_buffer;
-
-			chdlc_priv_area->end_addr_trace_buffer = 
-					trace_cfg_struct.end_addr_trace_buffer;
-
-		    	chdlc_priv_area->curr_trace_addr = 
-					trace_cfg_struct.next_trace_element_to_use;
-
-	    		chdlc_priv_area->available_buffer_space = 2000 - 
-								  sizeof(ip_pkt_t) -
-								  sizeof(udp_pkt_t) -
-							      	  sizeof(wp_mgmt_t) -
-								  sizeof(cblock_t) -
-							          sizeof(trace_info_t);	
-	       	     }
-		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
-		     mb->buffer_length = 0;
-	       	     chdlc_priv_area->TracingEnabled = 1;
-	       	     break;
-	   
-
-		case CPIPE_DISABLE_TRACING:
-		     if (chdlc_priv_area->TracingEnabled) {
-
-			/* OPERATE_DATALINE_MONITOR */
-			mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
-			mb->command = SET_TRACE_CONFIGURATION;
-    			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
-				trace_config = TRACE_INACTIVE;
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-		     }		
-
-		     chdlc_priv_area->TracingEnabled = 0;
-		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
-		     mb->buffer_length = 0;
-		     break;
-	   
-
-		case CPIPE_GET_TRACE_INFO:
-
-		     if (!chdlc_priv_area->TracingEnabled) {
-			chdlc_udp_pkt->cblock.return_code = 1;
-			mb->buffer_length = 0;
-			break;
-		     }
-
-  		     chdlc_udp_pkt->trace_info.ismoredata = 0x00;
-		     buffer_length = 0;	/* offset of packet already occupied */
-
-		     for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
-
-			trace_pkt_t *trace_pkt = (trace_pkt_t *)
-				&chdlc_udp_pkt->data[buffer_length];
-
-			sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
-			   	  (unsigned char *)&trace_element_struct,
-			   	  sizeof(TRACE_STATUS_ELEMENT_STRUCT));
-
-     			if (trace_element_struct.opp_flag == 0x00) {
-			 	break;
-			}
-
-			/* get pointer to real data */
-			data_ptr = trace_element_struct.ptr_data_bfr;
-
-			/* See if there is actual data on the trace buffer */
-			if (data_ptr){
-				data_length = trace_element_struct.trace_length;
-			}else{
-				data_length = 0;
-				chdlc_udp_pkt->trace_info.ismoredata = 0x01;
-			}
-	
-   			if( (chdlc_priv_area->available_buffer_space - buffer_length)
-				< ( sizeof(trace_pkt_t) + data_length) ) {
-
-                            /* indicate there are more frames on board & exit */
-				chdlc_udp_pkt->trace_info.ismoredata = 0x01;
-                               	break;
-                         }
-
-			trace_pkt->status = trace_element_struct.trace_type;
-
-			trace_pkt->time_stamp =
-				trace_element_struct.trace_time_stamp;
-
-			trace_pkt->real_length =
-				trace_element_struct.trace_length;
-
-			/* see if we can fit the frame into the user buffer */
-			real_len = trace_pkt->real_length;
-
-			if (data_ptr == 0) {
-			     	trace_pkt->data_avail = 0x00;
-			} else {
-				unsigned tmp = 0;
-
-				/* get the data from circular buffer
-				    must check for end of buffer */
-			        trace_pkt->data_avail = 0x01;
-
-				if ((data_ptr + real_len) >
-					     chdlc_priv_area->end_addr_trace_buffer + 1){
-
-				    	tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
-				    	sdla_peek(&card->hw, data_ptr,
-					       	  trace_pkt->data,tmp);
-				    	data_ptr = chdlc_priv_area->base_addr_trace_buffer;
-				}
-	
-		        	sdla_peek(&card->hw, data_ptr,
-					  &trace_pkt->data[tmp], real_len - tmp);
-			}	
-
-			/* zero the opp flag to show we got the frame */
-			ut_char = 0x00;
-			sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
-
-       			/* now move onto the next frame */
-       			chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
-
-       			/* check if we went over the last address */
-			if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
-				chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
-       			}
-
-            		if(trace_pkt->data_avail == 0x01) {
-				buffer_length += real_len - 1;
-			}
-	 
-	       	    	/* for the header */
-	            	buffer_length += sizeof(trace_pkt_t);
-
-		     }  /* For Loop */
-
-		     if (frames == chdlc_priv_area->number_trace_elements){
-			chdlc_udp_pkt->trace_info.ismoredata = 0x01;
-	             }
- 		     chdlc_udp_pkt->trace_info.num_frames = frames;
-		 
-    		     mb->buffer_length = buffer_length;
-		     chdlc_udp_pkt->cblock.buffer_length = buffer_length; 
-		 
-		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK; 
-		     
-		     break;
-
-
-		case CPIPE_FT1_READ_STATUS:
-			((unsigned char *)chdlc_udp_pkt->data )[0] =
-				flags->FT1_info_struct.parallel_port_A_input;
-
-			((unsigned char *)chdlc_udp_pkt->data )[1] =
-				flags->FT1_info_struct.parallel_port_B_input;
-				
-			chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
-			chdlc_udp_pkt->cblock.buffer_length = 2;
-			mb->buffer_length = 2;
-			break;
-
-		case CPIPE_ROUTER_UP_TIME:
-			do_gettimeofday( &tv );
-			chdlc_priv_area->router_up_time = tv.tv_sec - 
-					chdlc_priv_area->router_start_time;
-			*(unsigned long *)&chdlc_udp_pkt->data = 
-					chdlc_priv_area->router_up_time;	
-			mb->buffer_length = sizeof(unsigned long);
-			chdlc_udp_pkt->cblock.buffer_length = sizeof(unsigned long);
-			chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
-			break;
-
-   		case FT1_MONITOR_STATUS_CTRL:
-			/* Enable FT1 MONITOR STATUS */
-	        	if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||  
-				(chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
-			
-			     	if( rCount++ != 0 ) {
-					chdlc_udp_pkt->cblock.
-					return_code = COMMAND_OK;
-					mb->buffer_length = 1;
-		  			break;
-		    	     	}
-	      		}
-
-	      		/* Disable FT1 MONITOR STATUS */
-	      		if( chdlc_udp_pkt->data[0] == 0) {
-
-	      	   	     	if( --rCount != 0) {
-		  			chdlc_udp_pkt->cblock.
-					return_code = COMMAND_OK;
-					mb->buffer_length = 1;
-		  			break;
-	   	    	     	} 
-	      		} 	
-			goto dflt_1;
-
-		default:
-dflt_1:
-			/* it's a board command */
-			mb->command = chdlc_udp_pkt->cblock.command;
-			mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
-			if (mb->buffer_length) {
-				memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
-							data, mb->buffer_length);
-	      		} 
-			/* run the command on the board */
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-			if (err != COMMAND_OK) {
-				break;
-			}
-
-			/* copy the result back to our buffer */
-	         	memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t)); 
-			
-			if (mb->buffer_length) {
-	         		memcpy(&chdlc_udp_pkt->data, &mb->data, 
-								mb->buffer_length); 
-	      		}
-
-		} /* end of switch */
-     	} /* end of else */
-
-     	/* Fill UDP TTL */
-	chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl; 
-
-     	len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
-	
-
-     	if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
-
-		/* Must check if we interrupted if_send() routine. The
-		 * tx buffers might be used. If so drop the packet */
-	   	if (!test_bit(SEND_CRIT,&card->wandev.critical)) {
-		
-			if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
-				++ card->wandev.stats.tx_packets;
-				card->wandev.stats.tx_bytes += len;
-			}
-		}
-	} else {	
-	
-		/* Pass it up the stack
-    		   Allocate socket buffer */
-		if ((new_skb = dev_alloc_skb(len)) != NULL) {
-			/* copy data into new_skb */
-
- 	    		buf = skb_put(new_skb, len);
-  	    		memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
-
-            		/* Decapsulate pkt and pass it up the protocol stack */
-	    		new_skb->protocol = htons(ETH_P_IP);
-            		new_skb->dev = dev;
-	    		new_skb->mac.raw  = new_skb->data;
-	
-			netif_rx(new_skb);
-			dev->last_rx = jiffies;
-		} else {
-	    	
-			printk(KERN_INFO "%s: no socket buffers available!\n",
-					card->devname);
-  		}
-    	}
- 
-	chdlc_priv_area->udp_pkt_lgth = 0;
- 	
-	return 0;
-}
-
-/*============================================================================
- * Initialize Receive and Transmit Buffers.
- */
-
-static void init_chdlc_tx_rx_buff( sdla_t* card)
-{
-	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
-	CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
-	CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
-	char err;
-	
-	mb->buffer_length = 0;
-	mb->command = READ_CHDLC_CONFIGURATION;
-	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-
-	if(err != COMMAND_OK) {
-		if (card->wandev.dev){
-			chdlc_error(card,err,mb);
-		}
-		return;
-	}
-
-	if(card->hw.type == SDLA_S514) {
-		tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
-                (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
-                            ptr_CHDLC_Tx_stat_el_cfg_struct));
-        	rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
-                (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
-                            ptr_CHDLC_Rx_stat_el_cfg_struct));
-
-       		/* Setup Head and Tails for buffers */
-        	card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
-                tx_config->base_addr_Tx_status_elements);
-        	card->u.c.txbuf_last = 
-		(CHDLC_DATA_TX_STATUS_EL_STRUCT *)  
-                card->u.c.txbuf_base +
-		(tx_config->number_Tx_status_elements - 1);
-
-        	card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
-                rx_config->base_addr_Rx_status_elements);
-        	card->u.c.rxbuf_last =
-		(CHDLC_DATA_RX_STATUS_EL_STRUCT *)
-                card->u.c.rxbuf_base +
-		(rx_config->number_Rx_status_elements - 1);
-
- 		/* Set up next pointer to be used */
-        	card->u.c.txbuf = (void *)(card->hw.dpmbase +
-                tx_config->next_Tx_status_element_to_use);
-        	card->u.c.rxmb = (void *)(card->hw.dpmbase +
-                rx_config->next_Rx_status_element_to_use);
-	}
-        else {
-                tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
-			(((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
-			ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
-
-                rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
-			(((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
-			ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
-
-                /* Setup Head and Tails for buffers */
-                card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
-		(tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
-                card->u.c.txbuf_last =
-		(CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
-		+ (tx_config->number_Tx_status_elements - 1);
-                card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
-		(rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
-                card->u.c.rxbuf_last = 
-		(CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
-		+ (rx_config->number_Rx_status_elements - 1);
-
-                 /* Set up next pointer to be used */
-                card->u.c.txbuf = (void *)(card->hw.dpmbase +
-		(tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
-                card->u.c.rxmb = (void *)(card->hw.dpmbase +
-		(rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
-        }
-
-        /* Setup Actual Buffer Start and end addresses */
-        card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
-        card->u.c.rx_top  = rx_config->end_addr_Rx_buffer;
-
-}
-
-/*=============================================================================
- * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
- * _TEST_COUNTER times.
- */
-static int intr_test( sdla_t* card)
-{
-	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
-	int err,i;
-
-	Intr_test_counter = 0;
-	
-	err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
-
-	if (err == CMD_OK) { 
-		for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {	
-			mb->buffer_length  = 0;
-			mb->command = READ_CHDLC_CODE_VERSION;
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-			if (err != CMD_OK) 
-				chdlc_error(card, err, mb);
-		}
-	}
-	else {
-		return err;
-	}
-
-	err = chdlc_set_intr_mode(card, 0);
-
-	if (err != CMD_OK)
-		return err;
-
-	return 0;
-}
-
-/*==============================================================================
- * Determine what type of UDP call it is. CPIPEAB ?
- */
-static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
-{
-	 chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
-
-#ifdef _WAN_UDP_DEBUG
-		printk(KERN_INFO "SIG %s = %s\n\
-				  UPP %x = %x\n\
-				  PRT %x = %x\n\
-				  REQ %i = %i\n\
-				  36 th = %x 37th = %x\n",
-				  chdlc_udp_pkt->wp_mgmt.signature,
-				  UDPMGMT_SIGNATURE,
-				  chdlc_udp_pkt->udp_pkt.udp_dst_port,
-				  ntohs(card->wandev.udp_port),
-				  chdlc_udp_pkt->ip_pkt.protocol,
-				  UDPMGMT_UDP_PROTOCOL,
-				  chdlc_udp_pkt->wp_mgmt.request_reply,
-				  UDPMGMT_REQUEST,
-				  skb->data[36], skb->data[37]);
-#endif	
-		
-	if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
-	   (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
-	   (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
-	   (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
-
-		return UDP_CPIPE_TYPE;
-
-	}else{ 
-		return UDP_INVALID_TYPE;
-	}
-}
-
-/*============================================================================
- * Set PORT state.
- */
-static void port_set_state (sdla_t *card, int state)
-{
-        if (card->u.c.state != state)
-        {
-                switch (state)
-                {
-                case WAN_CONNECTED:
-                        printk (KERN_INFO "%s: Link connected!\n",
-                                card->devname);
-                      	break;
-
-                case WAN_CONNECTING:
-                        printk (KERN_INFO "%s: Link connecting...\n",
-                                card->devname);
-                        break;
-
-                case WAN_DISCONNECTED:
-                        printk (KERN_INFO "%s: Link disconnected!\n",
-                                card->devname);
-                        break;
-                }
-
-                card->wandev.state = card->u.c.state = state;
-		if (card->wandev.dev){
-			struct net_device *dev = card->wandev.dev;
-			chdlc_private_area_t *chdlc_priv_area = dev->priv;
-			chdlc_priv_area->common.state = state;
-		}
-        }
-}
-
-/*===========================================================================
- * config_chdlc
- *
- *	Configure the chdlc protocol and enable communications.		
- *
- *   	The if_open() function binds this function to the poll routine.
- *      Therefore, this function will run every time the chdlc interface
- *      is brought up. We cannot run this function from the if_open 
- *      because if_open does not have access to the remote IP address.
- *      
- *	If the communications are not enabled, proceed to configure
- *      the card and enable communications.
- *
- *      If the communications are enabled, it means that the interface
- *      was shutdown by ether the user or driver. In this case, we 
- *      have to check that the IP addresses have not changed.  If
- *      the IP addresses have changed, we have to reconfigure the firmware
- *      and update the changed IP addresses.  Otherwise, just exit.
- *
- */
-
-static int config_chdlc (sdla_t *card)
-{
-	struct net_device *dev = card->wandev.dev;
-	chdlc_private_area_t *chdlc_priv_area = dev->priv;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-
-	if (card->u.c.comm_enabled){
-
-		/* Jun 20. 2000: NC
-		 * IP addresses are not used in the API mode */
-		
-		if ((chdlc_priv_area->ip_local_tmp != chdlc_priv_area->ip_local ||
-		     chdlc_priv_area->ip_remote_tmp != chdlc_priv_area->ip_remote) && 
-		     card->u.c.usedby == WANPIPE) {
-			
-			/* The IP addersses have changed, we must
-                         * stop the communications and reconfigure
-                         * the card. Reason: the firmware must know
-                         * the local and remote IP addresses. */
-			disable_comm(card);
-			port_set_state(card, WAN_DISCONNECTED);
-			printk(KERN_INFO 
-				"%s: IP addresses changed!\n",
-					card->devname);
-			printk(KERN_INFO 
-				"%s: Restarting communications ...\n",
-					card->devname);
-		}else{ 
-			/* IP addresses are the same and the link is up, 
-                         * we don't have to do anything here. Therefore, exit */
-			return 0;
-		}
-	}
-
-	chdlc_priv_area->ip_local = chdlc_priv_area->ip_local_tmp;
-	chdlc_priv_area->ip_remote = chdlc_priv_area->ip_remote_tmp;
-
-
-	/* Setup the Board for asynchronous mode */
-	if (card->u.c.async_mode){
-		
-		if (set_asy_config(card)) {
-			printk (KERN_INFO "%s: Failed CHDLC Async configuration!\n",
-				card->devname);
-			return 0;
-		}
-	}else{
-		/* Setup the Board for CHDLC */
-		if (set_chdlc_config(card)) {
-			printk (KERN_INFO "%s: Failed CHDLC configuration!\n",
-				card->devname);
-			return 0;
-		}
-	}
-
-	/* Set interrupt mode and mask */
-        if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
-                		APP_INT_ON_GLOBAL_EXCEP_COND |
-                		APP_INT_ON_TX_FRAME |
-                		APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
-		printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
-				card->devname);
-		return 0;	
-        }
-	
-
-	/* Mask the Transmit and Timer interrupt */
-	flags->interrupt_info_struct.interrupt_permission &= 
-		~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
-
-	/* In TTY mode, receive interrupt will be enabled during
-	 * wanpipe_tty_open() operation */
-	if (card->tty_opt){
-		flags->interrupt_info_struct.interrupt_permission &= ~APP_INT_ON_RX_FRAME;
-	}
-
-	/* Enable communications */
- 	if (card->u.c.async_mode){
-		if (asy_comm_enable(card) != 0) {
-			printk(KERN_INFO "%s: Failed to enable async commnunication!\n",
-					card->devname);
-			flags->interrupt_info_struct.interrupt_permission = 0;
-			card->u.c.comm_enabled=0;
-			chdlc_set_intr_mode(card,0);
-			return 0;
-		}
-        }else{ 
-		if (chdlc_comm_enable(card) != 0) {
-			printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
-					card->devname);
-			flags->interrupt_info_struct.interrupt_permission = 0;
-			card->u.c.comm_enabled=0;
-			chdlc_set_intr_mode(card,0);
-			return 0;
-		}
-	}
-
-	/* Initialize Rx/Tx buffer control fields */
-	init_chdlc_tx_rx_buff(card);
-	port_set_state(card, WAN_CONNECTING);
-	return 0; 
-}
-
-
-/*============================================================
- * chdlc_poll
- *	
- * Rationale:
- * 	We cannot manipulate the routing tables, or
- *      ip addresses withing the interrupt. Therefore
- *      we must perform such actons outside an interrupt 
- *      at a later time. 
- *
- * Description:	
- *	CHDLC polling routine, responsible for 
- *     	shutting down interfaces upon disconnect
- *     	and adding/removing routes. 
- *      
- * Usage:        
- * 	This function is executed for each CHDLC  
- * 	interface through a tq_schedule bottom half.
- *      
- *      trigger_chdlc_poll() function is used to kick
- *      the chldc_poll routine.  
- */
-
-static void chdlc_poll(struct net_device *dev)
-{
-	chdlc_private_area_t *chdlc_priv_area;
-	sdla_t *card;
-	u8 check_gateway=0;	
-	SHARED_MEMORY_INFO_STRUCT* flags;
-
-	
-	if (!dev || (chdlc_priv_area=dev->priv) == NULL)
-		return;
-
-	card = chdlc_priv_area->card;
-	flags = card->u.c.flags;
-	
-	/* (Re)Configuraiton is in progress, stop what you are 
-	 * doing and get out */
-	if (test_bit(PERI_CRIT,&card->wandev.critical)){
-		clear_bit(POLL_CRIT,&card->wandev.critical);
-		return;
-	}
-	
-	/* if_open() function has triggered the polling routine
-	 * to determine the configured IP addresses.  Once the
-	 * addresses are found, trigger the chdlc configuration */
-	if (test_bit(0,&chdlc_priv_area->config_chdlc)){
-
-		chdlc_priv_area->ip_local_tmp  = get_ip_address(dev,WAN_LOCAL_IP);
-		chdlc_priv_area->ip_remote_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP);
-	
-	       /* Jun 20. 2000 Bug Fix
-	 	* Only perform this check in WANPIPE mode, since
-	 	* IP addresses are not used in the API mode. */
-	
-		if (chdlc_priv_area->ip_local_tmp == chdlc_priv_area->ip_remote_tmp && 
-		    card->u.c.slarp_timer == 0x00 && 
-		    !card->u.c.backup && 
-		    card->u.c.usedby == WANPIPE){
-
-			if (++chdlc_priv_area->ip_error > MAX_IP_ERRORS){
-				printk(KERN_INFO "\n%s: --- WARNING ---\n",
-						card->devname);
-				printk(KERN_INFO 
-				"%s: The local IP address is the same as the\n",
-						card->devname);
-				printk(KERN_INFO 
-				"%s: Point-to-Point IP address.\n",
-						card->devname);
-				printk(KERN_INFO "%s: --- WARNING ---\n\n",
-						card->devname);
-			}else{
-				clear_bit(POLL_CRIT,&card->wandev.critical);
-				chdlc_priv_area->poll_delay_timer.expires = jiffies+HZ;
-				add_timer(&chdlc_priv_area->poll_delay_timer);
-				return;
-			}
-		}
-
-		clear_bit(0,&chdlc_priv_area->config_chdlc);
-		clear_bit(POLL_CRIT,&card->wandev.critical);
-		
-		chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
-		flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
-		return;
-	}
-	/* Dynamic interface implementation, as well as dynamic
-	 * routing.  */
-	
-	switch (card->u.c.state){
-
-	case WAN_DISCONNECTED:
-
-		/* If the dynamic interface configuration is on, and interface 
-		 * is up, then bring down the netowrk interface */
-		
-		if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) && 
-		    !test_bit(DEV_DOWN,  &chdlc_priv_area->interface_down) &&		
-		    card->wandev.dev->flags & IFF_UP){	
-
-			printk(KERN_INFO "%s: Interface %s down.\n",
-				card->devname,card->wandev.dev->name);
-			change_dev_flags(card->wandev.dev,(card->wandev.dev->flags&~IFF_UP));
-			set_bit(DEV_DOWN,&chdlc_priv_area->interface_down);
-			chdlc_priv_area->route_status = NO_ROUTE;
-
-		}else{
-			/* We need to check if the local IP address is
-               	  	 * zero. If it is, we shouldn't try to remove it.
-                 	 */
-
-			if (card->wandev.dev->flags & IFF_UP && 
-		    	    get_ip_address(card->wandev.dev,WAN_LOCAL_IP) && 
-		    	    chdlc_priv_area->route_status != NO_ROUTE &&
-			    card->u.c.slarp_timer){
-
-				process_route(card);
-			}
-		}
-		break;
-
-	case WAN_CONNECTED:
-
-		/* In SMP machine this code can execute before the interface
-		 * comes up.  In this case, we must make sure that we do not
-		 * try to bring up the interface before dev_open() is finished */
-
-
-		/* DEV_DOWN will be set only when we bring down the interface
-		 * for the very first time. This way we know that it was us
-		 * that brought the interface down */
-		
-		if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) &&
-		    test_bit(DEV_DOWN,  &chdlc_priv_area->interface_down) &&
-		    !(card->wandev.dev->flags & IFF_UP)){
-			
-			printk(KERN_INFO "%s: Interface %s up.\n",
-				card->devname,card->wandev.dev->name);
-			change_dev_flags(card->wandev.dev,(card->wandev.dev->flags|IFF_UP));
-			clear_bit(DEV_DOWN,&chdlc_priv_area->interface_down);
-			check_gateway=1;
-		}
-
-		if (chdlc_priv_area->route_status == ADD_ROUTE && 
-		    card->u.c.slarp_timer){ 
-
-			process_route(card);
-			check_gateway=1;
-		}
-
-		if (chdlc_priv_area->gateway && check_gateway)
-			add_gateway(card,dev);
-
-		break;
-	}	
-
-	clear_bit(POLL_CRIT,&card->wandev.critical);
-}
-
-/*============================================================
- * trigger_chdlc_poll
- *
- * Description:
- * 	Add a chdlc_poll() work entry into the keventd work queue
- *      for a specific dlci/interface.  This will kick
- *      the fr_poll() routine at a later time. 
- *
- * Usage:
- * 	Interrupts use this to defer a taks to 
- *      a polling routine.
- *
- */	
-static void trigger_chdlc_poll(struct net_device *dev)
-{
-	chdlc_private_area_t *chdlc_priv_area;
-	sdla_t *card;
-
-	if (!dev)
-		return;
-	
-	if ((chdlc_priv_area = dev->priv)==NULL)
-		return;
-
-	card = chdlc_priv_area->card;
-	
-	if (test_and_set_bit(POLL_CRIT,&card->wandev.critical)){
-		return;
-	}
-	if (test_bit(PERI_CRIT,&card->wandev.critical)){
-		return; 
-	}
-	schedule_work(&chdlc_priv_area->poll_work);
-}
-
-
-static void chdlc_poll_delay (unsigned long dev_ptr)
-{
-	struct net_device *dev = (struct net_device *)dev_ptr;
-	trigger_chdlc_poll(dev);
-}
-
-
-void s508_lock (sdla_t *card, unsigned long *smp_flags)
-{
-	spin_lock_irqsave(&card->wandev.lock, *smp_flags);
-        if (card->next){
-        	spin_lock(&card->next->wandev.lock);
-	}
-}
-
-void s508_unlock (sdla_t *card, unsigned long *smp_flags)
-{
-        if (card->next){
-        	spin_unlock(&card->next->wandev.lock);
-        }
-        spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
-}
-
-//*********** TTY SECTION ****************
-
-static void wanpipe_tty_trigger_tx_irq(sdla_t *card)
-{
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-	INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
-	chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
-}
-
-static void wanpipe_tty_trigger_poll(sdla_t *card)
-{
-	schedule_work(&card->tty_work);
-}
-
-static void tty_poll_work (void* data)
-{
-	sdla_t *card = (sdla_t*)data;
-	struct tty_struct *tty;
-
-	if ((tty=card->tty)==NULL)
-		return;
-	
-	tty_wakeup(tty);
-#if defined(SERIAL_HAVE_POLL_WAIT)
-	wake_up_interruptible(&tty->poll_wait);
-#endif	
-	return;
-}
-
-static void wanpipe_tty_close(struct tty_struct *tty, struct file * filp)
-{
-	sdla_t *card;
-	unsigned long smp_flags;
-	
-	if (!tty || !tty->driver_data){
-		return;
-	}
-	
-	card = (sdla_t*)tty->driver_data;
-	
-	if (!card)
-		return;
-
-	printk(KERN_INFO "%s: Closing TTY Driver!\n",
-			card->devname);
-
-	/* Sanity Check */
-	if (!card->tty_open)
-		return;
-	
-	wanpipe_close(card);
-	if (--card->tty_open == 0){
-
-		lock_adapter_irq(&card->wandev.lock,&smp_flags);	
-		card->tty=NULL;
-		chdlc_disable_comm_shutdown(card);
-		unlock_adapter_irq(&card->wandev.lock,&smp_flags);
-
-		kfree(card->tty_buf);
-		card->tty_buf = NULL;			
-		kfree(card->tty_rx);
-		card->tty_rx = NULL;
-	}
-	return;
-}
-static int wanpipe_tty_open(struct tty_struct *tty, struct file * filp)
-{
-	unsigned long smp_flags;
-	sdla_t *card;
-	
-	if (!tty){
-		return -ENODEV;
-	}
-	
-	if (!tty->driver_data){
-		int port;
-		port = tty->index;
-		if ((port < 0) || (port >= NR_PORTS)) 
-			return -ENODEV;
-		
-		tty->driver_data = WAN_CARD(port);
-		if (!tty->driver_data)
-			return -ENODEV;
-	}
-
-	card = (sdla_t*)tty->driver_data;
-
-	if (!card){
-		lock_adapter_irq(&card->wandev.lock,&smp_flags);	
-		card->tty=NULL;
-		unlock_adapter_irq(&card->wandev.lock,&smp_flags);
-		return -ENODEV;
-	}
-
-	printk(KERN_INFO "%s: Opening TTY Driver!\n",
-			card->devname);
-
-	if (card->tty_open == 0){
-		lock_adapter_irq(&card->wandev.lock,&smp_flags);	
-		card->tty=tty;
-		unlock_adapter_irq(&card->wandev.lock,&smp_flags);
-
-		if (!card->tty_buf){
-			card->tty_buf = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL);
-			if (!card->tty_buf){
-				card->tty_buf=NULL;
-				card->tty=NULL;
-				return -ENOMEM;	
-			}
-		}
-
-		if (!card->tty_rx){
-			card->tty_rx = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL);
-			if (!card->tty_rx){
-				/* Free the buffer above */
-				kfree(card->tty_buf);
-				card->tty_buf=NULL;
-				card->tty=NULL;
-				return -ENOMEM;	
-			}
-		}
-	}
-
-	++card->tty_open;
-	wanpipe_open(card);
-	return 0;
-}
-
-static int wanpipe_tty_write(struct tty_struct * tty, const unsigned char *buf, int count)
-{
-	unsigned long smp_flags=0;
-	sdla_t *card=NULL;
-
-	if (!tty){
-		dbg_printk(KERN_INFO "NO TTY in Write\n");
-		return -ENODEV;
-	}
-
-	card = (sdla_t *)tty->driver_data;
-			
-	if (!card){
-		dbg_printk(KERN_INFO "No Card in TTY Write\n");
-		return -ENODEV;
-	}	
-
-	if (count > card->wandev.mtu){
-		dbg_printk(KERN_INFO "Frame too big in Write %i Max: %i\n",
-				count,card->wandev.mtu);
-		return -EINVAL;
-	}
-	
-	if (card->wandev.state != WAN_CONNECTED){
-		dbg_printk(KERN_INFO "Card not connected in TTY Write\n");
-		return -EINVAL;
-	}
-
-	/* Lock the 508 Card: SMP is supported */
-      	if(card->hw.type != SDLA_S514){
-		s508_lock(card,&smp_flags);
-	} 
-	
-	if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){
-		printk(KERN_INFO "%s: Critical in TTY Write\n",
-				card->devname);
-		
-		/* Lock the 508 Card: SMP is supported */
-		if(card->hw.type != SDLA_S514)
-			s508_unlock(card,&smp_flags);
-		
-		return -EINVAL; 
-	}
-	
- 	if (chdlc_send(card,(void*)buf,count)){
-		dbg_printk(KERN_INFO "%s: Failed to send, retry later: kernel!\n",
-				card->devname);
-		clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
-
-		wanpipe_tty_trigger_tx_irq(card);
-		
-		if(card->hw.type != SDLA_S514)
-			s508_unlock(card,&smp_flags);
-		return 0;
-	}
-	dbg_printk(KERN_INFO "%s: Packet sent OK: %i\n",card->devname,count);
-	clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
-	
-	if(card->hw.type != SDLA_S514)
-		s508_unlock(card,&smp_flags);
-
-	return count;
-}
-
-static void wanpipe_tty_receive(sdla_t *card, unsigned addr, unsigned int len)
-{
-	unsigned offset=0;
-	unsigned olen=len;
-	char fp=0;
-	struct tty_struct *tty;
-	int i;
-	struct tty_ldisc *ld;
-	
-	if (!card->tty_open){
-		dbg_printk(KERN_INFO "%s: TTY not open during receive\n",
-				card->devname);
-		return;
-	}
-	
-	if ((tty=card->tty) == NULL){
-		dbg_printk(KERN_INFO "%s: No TTY on receive\n",
-				card->devname);
-		return;
-	}
-	
-	if (!tty->driver_data){
-		dbg_printk(KERN_INFO "%s: No Driver Data, or Flip on receive\n",
-				card->devname);
-		return;
-	}
-	
-
-	if (card->u.c.async_mode){
-		if ((tty->flip.count+len) >= TTY_FLIPBUF_SIZE){
-			if (net_ratelimit()){
-				printk(KERN_INFO 
-					"%s: Received packet size too big: %i bytes, Max: %i!\n",
-					card->devname,len,TTY_FLIPBUF_SIZE);
-			}
-			return;
-		}
-
-		
-		if((addr + len) > card->u.c.rx_top + 1) {
-			offset = card->u.c.rx_top - addr + 1;
-			
-			sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, offset);
-			
-			addr = card->u.c.rx_base;
-			len -= offset;
-			
-			tty->flip.char_buf_ptr+=offset;
-			tty->flip.count+=offset;
-			for (i=0;i<offset;i++){
-				*tty->flip.flag_buf_ptr = 0;
-				tty->flip.flag_buf_ptr++;
-			}
-		}
-		
-		sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, len);
-			
-		tty->flip.char_buf_ptr+=len;
-		card->tty->flip.count+=len;
-		for (i=0;i<len;i++){
-			*tty->flip.flag_buf_ptr = 0;
-			tty->flip.flag_buf_ptr++;
-		}
-
-		tty->low_latency=1;
-		tty_flip_buffer_push(tty);
-	}else{
-		if (!card->tty_rx){	
-			if (net_ratelimit()){
-				printk(KERN_INFO 
-				"%s: Receive sync buffer not available!\n",
-				 card->devname);
-			}
-			return;
-		}
-	
-		if (len > TTY_CHDLC_MAX_MTU){
-			if (net_ratelimit()){
-				printk(KERN_INFO 
-				"%s: Received packet size too big: %i bytes, Max: %i!\n",
-					card->devname,len,TTY_FLIPBUF_SIZE);
-			}
-			return;
-		}
-
-		
-		if((addr + len) > card->u.c.rx_top + 1) {
-			offset = card->u.c.rx_top - addr + 1;
-			
-			sdla_peek(&card->hw, addr, card->tty_rx, offset);
-			
-			addr = card->u.c.rx_base;
-			len -= offset;
-		}
-		sdla_peek(&card->hw, addr, card->tty_rx+offset, len);
-		ld = tty_ldisc_ref(tty);
-		if (ld) {
-			if (ld->receive_buf)
-				ld->receive_buf(tty,card->tty_rx,&fp,olen);
-			tty_ldisc_deref(ld);
-		}else{
-			if (net_ratelimit()){
-				printk(KERN_INFO 
-					"%s: NO TTY Sync line discipline!\n",
-					card->devname);
-			}
-		}
-	}
-
-	dbg_printk(KERN_INFO "%s: Received Data %i\n",card->devname,olen);
-	return;
-}
-
-#if 0
-static int wanpipe_tty_ioctl(struct tty_struct *tty, struct file * file,
-		    unsigned int cmd, unsigned long arg)
-{
-	return -ENOIOCTLCMD;
-}
-#endif
-
-static void wanpipe_tty_stop(struct tty_struct *tty)
-{
-	return;
-}
-
-static void wanpipe_tty_start(struct tty_struct *tty)
-{
-	return;
-}
-
-static int config_tty (sdla_t *card)
-{
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-
-	/* Setup the Board for asynchronous mode */
-	if (card->u.c.async_mode){
-		
-		if (set_asy_config(card)) {
-			printk (KERN_INFO "%s: Failed CHDLC Async configuration!\n",
-				card->devname);
-			return -EINVAL;
-		}
-	}else{
-		/* Setup the Board for CHDLC */
-		if (set_chdlc_config(card)) {
-			printk (KERN_INFO "%s: Failed CHDLC configuration!\n",
-				card->devname);
-			return -EINVAL;
-		}
-	}
-
-	/* Set interrupt mode and mask */
-        if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
-                		APP_INT_ON_GLOBAL_EXCEP_COND |
-                		APP_INT_ON_TX_FRAME |
-                		APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
-		printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
-				card->devname);
-		return -EINVAL;	
-        }
-	
-
-	/* Mask the Transmit and Timer interrupt */
-	flags->interrupt_info_struct.interrupt_permission &= 
-		~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
-
-	
-	/* Enable communications */
- 	if (card->u.c.async_mode){
-		if (asy_comm_enable(card) != 0) {
-			printk(KERN_INFO "%s: Failed to enable async commnunication!\n",
-					card->devname);
-			flags->interrupt_info_struct.interrupt_permission = 0;
-			card->u.c.comm_enabled=0;
-			chdlc_set_intr_mode(card,0);
-			return -EINVAL;
-		}
-        }else{ 
-		if (chdlc_comm_enable(card) != 0) {
-			printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
-					card->devname);
-			flags->interrupt_info_struct.interrupt_permission = 0;
-			card->u.c.comm_enabled=0;
-			chdlc_set_intr_mode(card,0);
-			return -EINVAL;
-		}
-	}
-
-	/* Initialize Rx/Tx buffer control fields */
-	init_chdlc_tx_rx_buff(card);
-	port_set_state(card, WAN_CONNECTING);
-	return 0; 
-}
-
-
-static int change_speed(sdla_t *card, struct tty_struct *tty,
-			 struct termios *old_termios)
-{
-	int	baud, ret=0;
-	unsigned cflag; 
-	int	dbits,sbits,parity,handshaking;
-
-	cflag = tty->termios->c_cflag;
-
-	/* There is always one stop bit */
-	sbits=WANOPT_ONE;
-	
-	/* Parity is defaulted to NONE */
-	parity = WANOPT_NONE;
-
-	handshaking=0;
-	
-	/* byte size and parity */
-	switch (cflag & CSIZE) {
-	      case CS5: dbits = 5; break;
-	      case CS6: dbits = 6; break;
-	      case CS7: dbits = 7; break;
-	      case CS8: dbits = 8; break;
-	      /* Never happens, but GCC is too dumb to figure it out */
-	      default:  dbits = 8; break;
-	}
-	
-	/* One more stop bit should be supported, thus increment
-	 * the number of stop bits Max=2 */
-	if (cflag & CSTOPB) {
-		sbits = WANOPT_TWO;
-	}
-	if (cflag & PARENB) {
-		parity = WANOPT_EVEN;
-	}
-	if (cflag & PARODD){
-		parity = WANOPT_ODD;
-	}
-
-	/* Determine divisor based on baud rate */
-	baud = tty_get_baud_rate(tty);
-
-	if (!baud)
-		baud = 9600;	/* B0 transition handled in rs_set_termios */
-
-	if (cflag & CRTSCTS) {
-		handshaking|=ASY_RTS_HS_FOR_RX;
-	}
-	
-	if (I_IGNPAR(tty))
-		parity = WANOPT_NONE;
-
-	if (I_IXOFF(tty)){
-		handshaking|=ASY_XON_XOFF_HS_FOR_RX;
-		handshaking|=ASY_XON_XOFF_HS_FOR_TX;
-	}
-
-	if (I_IXON(tty)){
-		handshaking|=ASY_XON_XOFF_HS_FOR_RX;
-		handshaking|=ASY_XON_XOFF_HS_FOR_TX;
-	}
-
-	if (card->u.c.async_mode){
-		if (card->wandev.bps != baud)
-			ret=1;
-		card->wandev.bps = baud;
-	}
-
-	if (card->u.c.async_mode){
-		if (card->u.c.protocol_options != handshaking)
-			ret=1;
-		card->u.c.protocol_options = handshaking;
-
-		if (card->u.c.tx_bits_per_char != dbits)
-			ret=1;
-		card->u.c.tx_bits_per_char = dbits;
-
-		if (card->u.c.rx_bits_per_char != dbits)
-			ret=1;
-		card->u.c.rx_bits_per_char = dbits;
-		
-		if (card->u.c.stop_bits != sbits)
-			ret=1;
-		card->u.c.stop_bits = sbits;
-
-		if (card->u.c.parity != parity)
-			ret=1;
-		card->u.c.parity = parity;	
-
-		card->u.c.break_timer = 50;
-		card->u.c.inter_char_timer = 10;
-		card->u.c.rx_complete_length = 100;
-		card->u.c.xon_char = 0xFE;
-	}else{
-		card->u.c.protocol_options = HDLC_STREAMING_MODE;
-	}
-	
-	return ret;
-}
-
-	
-static void wanpipe_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
-{
-	sdla_t *card;
-	int err=1;
-
-	if (!tty){
-		return;
-	}
-
-	card = (sdla_t *)tty->driver_data;
-			
-	if (!card)
-		return;
-
-	if (change_speed(card, tty, old_termios) || !card->u.c.comm_enabled){
-		unsigned long smp_flags;
-		
-		if (card->u.c.comm_enabled){
-			lock_adapter_irq(&card->wandev.lock,&smp_flags);
-			chdlc_disable_comm_shutdown(card);
-			unlock_adapter_irq(&card->wandev.lock,&smp_flags);
-		}
-		lock_adapter_irq(&card->wandev.lock,&smp_flags);
-		err = config_tty(card);
-		unlock_adapter_irq(&card->wandev.lock,&smp_flags);
-		if (card->u.c.async_mode){
-			printk(KERN_INFO "%s: TTY Async Configuration:\n"
-				 "   Baud        =%i\n"
-				 "   Handshaking =%s\n"
-				 "   Tx Dbits    =%i\n"
-				 "   Rx Dbits    =%i\n"
-				 "   Parity      =%s\n"
-				 "   Stop Bits   =%i\n",
-				 card->devname,
-				 card->wandev.bps,
-				 opt_decode[card->u.c.protocol_options],
-				 card->u.c.tx_bits_per_char,
-				 card->u.c.rx_bits_per_char,
-				 p_decode[card->u.c.parity] ,
-				 card->u.c.stop_bits);
-		}else{
-			printk(KERN_INFO "%s: TTY Sync Configuration:\n"
-				 "   Baud        =%i\n"
-				 "   Protocol    =HDLC_STREAMING\n",
-				 card->devname,card->wandev.bps);
-		}
-		if (!err){
-			port_set_state(card,WAN_CONNECTED);
-		}else{
-			port_set_state(card,WAN_DISCONNECTED);
-		}
-	}
-	return;
-}
-
-static void wanpipe_tty_put_char(struct tty_struct *tty, unsigned char ch)
-{
-	sdla_t *card;
-	unsigned long smp_flags=0;
-
-	if (!tty){
-		return;
-	}
-	
-	card = (sdla_t *)tty->driver_data;
-			
-	if (!card)
-		return;
-
-	if (card->wandev.state != WAN_CONNECTED)
-		return;
-
-	if(card->hw.type != SDLA_S514)
-		s508_lock(card,&smp_flags);
-	
-	if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){
-		
-		wanpipe_tty_trigger_tx_irq(card);
-
-		if(card->hw.type != SDLA_S514)
-			s508_unlock(card,&smp_flags);
-		return;
-	}
-
-	if (chdlc_send(card,(void*)&ch,1)){
-		wanpipe_tty_trigger_tx_irq(card);
-		dbg_printk("%s: Failed to TX char!\n",card->devname);
-	}
-	
-	dbg_printk("%s: Char TX OK\n",card->devname);
-	
-	clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
-	
-	if(card->hw.type != SDLA_S514)
-		s508_unlock(card,&smp_flags);
-	
-	return;
-}
-
-static void wanpipe_tty_flush_chars(struct tty_struct *tty)
-{
-	return;
-}
-
-static void wanpipe_tty_flush_buffer(struct tty_struct *tty)
-{
-	if (!tty)
-		return;
-	
-#if defined(SERIAL_HAVE_POLL_WAIT)
-	wake_up_interruptible(&tty->poll_wait);
-#endif
-	tty_wakeup(tty);
-	return;
-}
-
-/*
- * This function is used to send a high-priority XON/XOFF character to
- * the device
- */
-static void wanpipe_tty_send_xchar(struct tty_struct *tty, char ch)
-{
-	return;
-}
-
-
-static int wanpipe_tty_chars_in_buffer(struct tty_struct *tty)
-{
-	return 0;
-}
-
-
-static int wanpipe_tty_write_room(struct tty_struct *tty)
-{
-	sdla_t *card;
-
-	printk(KERN_INFO "TTY Write Room\n");
-	
-	if (!tty){
-		return 0;
-	}
-
-	card = (sdla_t *)tty->driver_data;
-	if (!card)
-		return 0;
-
-	if (card->wandev.state != WAN_CONNECTED)
-		return 0;
-	
-	return SEC_MAX_NO_DATA_BYTES_IN_FRAME;
-}
-
-
-static int set_modem_status(sdla_t *card, unsigned char data)
-{
-	CHDLC_MAILBOX_STRUCT *mb = card->mbox;
-	int err;
-
-	mb->buffer_length=1;
-	mb->command=SET_MODEM_STATUS;
-	mb->data[0]=data;
-	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-	if (err != COMMAND_OK) 
-		chdlc_error (card, err, mb);
-	
-	return err;
-}
-
-static void wanpipe_tty_hangup(struct tty_struct *tty)
-{
-	sdla_t *card;
-	unsigned long smp_flags;
-
-	printk(KERN_INFO "TTY Hangup!\n");
-	
-	if (!tty){
-		return;
-	}
-
-	card = (sdla_t *)tty->driver_data;
-	if (!card)
-		return;
-
-	lock_adapter_irq(&card->wandev.lock,&smp_flags);
-	set_modem_status(card,0);
-	unlock_adapter_irq(&card->wandev.lock,&smp_flags);
-	return;
-}
-
-static void wanpipe_tty_break(struct tty_struct *tty, int break_state)
-{
-	return;
-}
-
-static void wanpipe_tty_wait_until_sent(struct tty_struct *tty, int timeout)
-{
-	return;
-}
-
-static void wanpipe_tty_throttle(struct tty_struct * tty)
-{
-	return;
-}
-
-static void wanpipe_tty_unthrottle(struct tty_struct * tty)
-{
-	return;
-}
-
-int wanpipe_tty_read_proc(char *page, char **start, off_t off, int count,
-		 int *eof, void *data)
-{
-	return 0;
-}
-
-/*
- * The serial driver boot-time initialization code!
- */
-int wanpipe_tty_init(sdla_t *card)
-{
-	struct serial_state * state;
-	
-	/* Initialize the tty_driver structure */
-
-	if (card->tty_minor < 0 || card->tty_minor > NR_PORTS){
-		printk(KERN_INFO "%s: Illegal Minor TTY number (0-4): %i\n",
-				card->devname,card->tty_minor);
-		return -EINVAL;
-	}
-
-	if (WAN_CARD(card->tty_minor)){
-		printk(KERN_INFO "%s: TTY Minor %i, already in use\n",
-				card->devname,card->tty_minor);
-		return -EBUSY;
-	}
-
-	if (tty_init_cnt==0){
-		
-		printk(KERN_INFO "%s: TTY %s Driver Init: Major %i, Minor Range %i-%i\n",
-				card->devname,
-				card->u.c.async_mode ? "ASYNC" : "SYNC",
-				WAN_TTY_MAJOR,MIN_PORT,MAX_PORT);
-		
-		tty_driver_mode = card->u.c.async_mode;
-		
-		memset(&serial_driver, 0, sizeof(struct tty_driver));
-		serial_driver.magic = TTY_DRIVER_MAGIC;
-		serial_driver.owner = THIS_MODULE;
-		serial_driver.driver_name = "wanpipe_tty"; 
-		serial_driver.name = "ttyW";
-		serial_driver.major = WAN_TTY_MAJOR;
-		serial_driver.minor_start = WAN_TTY_MINOR;
-		serial_driver.num = NR_PORTS; 
-		serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
-		serial_driver.subtype = SERIAL_TYPE_NORMAL;
-		
-		serial_driver.init_termios = tty_std_termios;
-		serial_driver.init_termios.c_cflag =
-			B9600 | CS8 | CREAD | HUPCL | CLOCAL;
-		serial_driver.flags = TTY_DRIVER_REAL_RAW;
-		
-		serial_driver.refcount = 1;	/* !@!@^#^&!! */
-
-		serial_driver.open = wanpipe_tty_open;
-		serial_driver.close = wanpipe_tty_close;
-		serial_driver.write = wanpipe_tty_write;
-		
-		serial_driver.put_char = wanpipe_tty_put_char;
-		serial_driver.flush_chars = wanpipe_tty_flush_chars;
-		serial_driver.write_room = wanpipe_tty_write_room;
-		serial_driver.chars_in_buffer = wanpipe_tty_chars_in_buffer;
-		serial_driver.flush_buffer = wanpipe_tty_flush_buffer;
-		//serial_driver.ioctl = wanpipe_tty_ioctl;
-		serial_driver.throttle = wanpipe_tty_throttle;
-		serial_driver.unthrottle = wanpipe_tty_unthrottle;
-		serial_driver.send_xchar = wanpipe_tty_send_xchar;
-		serial_driver.set_termios = wanpipe_tty_set_termios;
-		serial_driver.stop = wanpipe_tty_stop;
-		serial_driver.start = wanpipe_tty_start;
-		serial_driver.hangup = wanpipe_tty_hangup;
-		serial_driver.break_ctl = wanpipe_tty_break;
-		serial_driver.wait_until_sent = wanpipe_tty_wait_until_sent;
-		serial_driver.read_proc = wanpipe_tty_read_proc;
-		
-		if (tty_register_driver(&serial_driver)){
-			printk(KERN_INFO "%s: Failed to register serial driver!\n",
-					card->devname);
-		}
-	}
-
-
-	/* The subsequent ports must comply to the initial configuration */
-	if (tty_driver_mode != card->u.c.async_mode){
-		printk(KERN_INFO "%s: Error: TTY Driver operation mode mismatch!\n",
-				card->devname);
-		printk(KERN_INFO "%s: The TTY driver is configured for %s!\n",
-				card->devname, tty_driver_mode ? "ASYNC" : "SYNC");
-		return -EINVAL;
-	}
-	
-	tty_init_cnt++;
-	
-	printk(KERN_INFO "%s: Initializing TTY %s Driver Minor %i\n",
-			card->devname,
-			tty_driver_mode ? "ASYNC" : "SYNC",
-			card->tty_minor);
-	
-	tty_card_map[card->tty_minor] = card;
-	state = &rs_table[card->tty_minor];
-	
-	state->magic = SSTATE_MAGIC;
-	state->line = 0;
-	state->type = PORT_UNKNOWN;
-	state->custom_divisor = 0;
-	state->close_delay = 5*HZ/10;
-	state->closing_wait = 30*HZ;
-	state->icount.cts = state->icount.dsr = 
-		state->icount.rng = state->icount.dcd = 0;
-	state->icount.rx = state->icount.tx = 0;
-	state->icount.frame = state->icount.parity = 0;
-	state->icount.overrun = state->icount.brk = 0;
-	state->irq = card->wandev.irq; 
-
-	INIT_WORK(&card->tty_work, tty_poll_work, (void*)card);
-	return 0;
-}
-
-
-MODULE_LICENSE("GPL");
-
-/****** End ****************************************************************/
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
deleted file mode 100644
index 7f1ce9d..0000000
--- a/drivers/net/wan/sdla_fr.c
+++ /dev/null
@@ -1,5061 +0,0 @@
-/*****************************************************************************
-* sdla_fr.c	WANPIPE(tm) Multiprotocol WAN Link Driver. Frame relay module.
-*
-* Author(s):	Nenad Corbic  <ncorbic@sangoma.com>
-*		Gideon Hack
-*
-* Copyright:	(c) 1995-2001 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.
-* ============================================================================
-* Nov 23, 2000  Nenad Corbic    o Added support for 2.4.X kernels
-* Nov 15, 2000  David Rokavarg  
-*               Nenad Corbic	o Added frame relay bridging support.
-* 				  Original code from Mark Wells and Kristian Hoffmann has
-* 				  been integrated into the frame relay driver.
-* Nov 13, 2000  Nenad Corbic    o Added true interface type encoding option.
-* 				  Tcpdump doesn't support Frame Relay inteface
-* 				  types, to fix this true type option will set
-* 				  the interface type to RAW IP mode.
-* Nov 07, 2000  Nenad Corbic	o Added security features for UDP debugging:
-*                                 Deny all and specify allowed requests.
-* Nov 06, 2000  Nenad Corbic	o Wanpipe interfaces conform to raw packet interfaces.  
-*                                 Moved the if_header into the if_send() routine.
-*                                 The if_header() was breaking the libpcap 
-*                                 support. i.e. support for tcpdump, ethereal ...
-* Oct 12. 2000  Nenad Corbic    o Added error message in fr_configure
-* Jul 31, 2000  Nenad Corbic	o Fixed the Router UP Time.
-* Apr 28, 2000  Nenad Corbic	o Added the option to shutdown an interface
-*                                 when the channel gets disconnected.
-* Apr 28, 2000  Nenad Corbic 	o Added M.Grants patch: disallow duplicate
-*                                 interface setups. 
-* Apr 25, 2000  Nenad Corbic	o Added M.Grants patch: dynamically add/remove 
-*                                 new dlcis/interfaces.
-* Mar 23, 2000  Nenad Corbic 	o Improved task queue, bh handling.
-* Mar 16, 2000	Nenad Corbic	o Added Inverse ARP support
-* Mar 13, 2000  Nenad Corbic	o Added new socket API support.
-* Mar 06, 2000  Nenad Corbic	o Bug Fix: corrupted mbox recovery.
-* Feb 24, 2000  Nenad Corbic    o Fixed up FT1 UDP debugging problem.
-* Dev 15, 1999  Nenad Corbic    o Fixed up header files for 2.0.X kernels
-*
-* Nov 08, 1999  Nenad Corbic    o Combined all debug UDP calls into one function
-*                               o Removed the ARP support. This has to be done
-*                                 in the next version.
-*                               o Only a Node can implement NO signalling.
-*                                 Initialize DLCI during if_open() if NO 
-*				  signalling.
-*				o Took out IPX support, implement in next
-*                                 version
-* Sep 29, 1999  Nenad Corbic	o Added SMP support and changed the update
-*                                 function to use timer interrupt.
-*				o Fixed the CIR bug:  Set the value of BC
-*                                 to CIR when the CIR is enabled.
-*  				o Updated comments, statistics and tracing.
-* Jun 02, 1999	Gideon Hack	o Updated for S514 support.
-* Sep 18, 1998	Jaspreet Singh	o Updated for 2.2.X kernels.
-* Jul 31, 1998	Jaspreet Singh	o Removed wpf_poll routine.  The channel/DLCI 
-*				  status is received through an event interrupt.
-* Jul 08, 1998	David Fong	o Added inverse ARP support.
-* Mar 26, 1997	Jaspreet Singh	o Returning return codes for failed UDP cmds.
-* Jan 28, 1997	Jaspreet Singh  o Improved handling of inactive DLCIs.
-* Dec 30, 1997	Jaspreet Singh	o Replaced dev_tint() with mark_bh(NET_BH)
-* Dec 16, 1997	Jaspreet Singh	o Implemented Multiple IPX support.
-* Nov 26, 1997	Jaspreet Singh	o Improved load sharing with multiple boards
-*				o Added Cli() to protect enabling of interrupts
-*				  while polling is called.
-* Nov 24, 1997	Jaspreet Singh	o Added counters to avoid enabling of interrupts
-*				  when they have been disabled by another
-*				  interface or routine (eg. wpf_poll).
-* Nov 06, 1997	Jaspreet Singh	o Added INTR_TEST_MODE to avoid polling	
-*				  routine disable interrupts during interrupt
-*				  testing.
-* Oct 20, 1997  Jaspreet Singh  o Added hooks in for Router UP time.
-* Oct 16, 1997  Jaspreet Singh  o The critical flag is used to maintain flow
-*                                 control by avoiding RACE conditions.  The
-*                                 cli() and restore_flags() are taken out.
-*                                 The fr_channel structure is appended for 
-*                                 Driver Statistics.
-* Oct 15, 1997  Farhan Thawar    o updated if_send() and receive for IPX
-* Aug 29, 1997  Farhan Thawar    o Removed most of the cli() and sti()
-*                                o Abstracted the UDP management stuff
-*                                o Now use tbusy and critical more intelligently
-* Jul 21, 1997  Jaspreet Singh	 o Can configure T391, T392, N391, N392 & N393
-*				   through router.conf.
-*				 o Protected calls to sdla_peek() by adDing 
-*				   save_flags(), cli() and restore_flags().
-*				 o Added error message for Inactive DLCIs in
-*				   fr_event() and update_chan_state().
-*				 o Fixed freeing up of buffers using kfree() 
-*			           when packets are received.
-* Jul 07, 1997	Jaspreet Singh	 o Added configurable TTL for UDP packets 
-*				 o Added ability to discard multicast and 
-*				   broadcast source addressed packets
-* Jun 27, 1997	Jaspreet Singh	 o Added FT1 monitor capabilities 
-*				   New case (0x44) statement in if_send routine 
-*				   Added a global variable rCount to keep track
-*			 	   of FT1 status enabled on the board.
-* May 29, 1997	Jaspreet Singh	 o Fixed major Flow Control Problem
-*				   With multiple boards a problem was seen where
-*				   the second board always stopped transmitting
-*				   packet after running for a while. The code
-*				   got into a stage where the interrupts were
-*				   disabled and dev->tbusy was set to 1.
-*                  		   This caused the If_send() routine to get into
-*                                  the if clause for it(0,dev->tbusy) 
-*				   forever.
-*				   The code got into this stage due to an 
-*				   interrupt occurring within the if clause for 
-*				   set_bit(0,dev->tbusy).  Since an interrupt 
-*				   disables furhter transmit interrupt and 
-* 				   makes dev->tbusy = 0, this effect was undone 
-*                                  by making dev->tbusy = 1 in the if clause.
-*				   The Fix checks to see if Transmit interrupts
-*				   are disabled then do not make dev->tbusy = 1
-* 	   			   Introduced a global variable: int_occur and
-*				   added tx_int_enabled in the wan_device 
-*				   structure.	
-* May 21, 1997  Jaspreet Singh   o Fixed UDP Management for multiple
-*                                  boards.
-*
-* Apr 25, 1997  Farhan Thawar    o added UDP Management stuff
-*                                o fixed bug in if_send() and tx_intr() to
-*                                  sleep and wakeup all devices
-* Mar 11, 1997  Farhan Thawar   Version 3.1.1
-*                                o fixed (+1) bug in fr508_rx_intr()
-*                                o changed if_send() to return 0 if
-*                                  wandev.critical() is true
-*                                o free socket buffer in if_send() if
-*                                  returning 0 
-*                                o added tx_intr() routine
-* Jan 30, 1997	Gene Kozin	Version 3.1.0
-*				 o implemented exec() entry point
-*				 o fixed a bug causing driver configured as
-*				   a FR switch to be stuck in WAN_
-*				   mode
-* Jan 02, 1997	Gene Kozin	Initial version.
-*****************************************************************************/
-
-#include <linux/module.h>
-#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/slab.h>	/* kmalloc(), kfree() */
-#include <linux/wanrouter.h>	/* WAN router definitions */
-#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
-#include <linux/workqueue.h>
-#include <linux/if_arp.h>	/* ARPHRD_* defines */
-#include <asm/byteorder.h>	/* htons(), etc. */
-#include <asm/io.h>		/* for inb(), outb(), etc. */
-#include <linux/time.h>	 	/* for do_gettimeofday */	
-#include <linux/in.h>		/* sockaddr_in */
-#include <linux/jiffies.h>	/* time_after() macro */
-#include <asm/errno.h>
-
-#include <linux/ip.h>
-#include <linux/if.h>
-
-#include <linux/if_wanpipe_common.h>	/* Wanpipe Socket */
-#include <linux/if_wanpipe.h>	
-
-#include <linux/sdla_fr.h>		/* frame relay firmware API definitions */
-
-#include <asm/uaccess.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-
-#include <net/route.h>          	/* Dynamic Route Creation */
-#include <linux/etherdevice.h>		/* eth_type_trans() used for bridging */
-#include <linux/random.h>
-
-/****** Defines & Macros ****************************************************/
-
-#define	MAX_CMD_RETRY	10		/* max number of firmware retries */
-
-#define	FR_HEADER_LEN	8		/* max encapsulation header size */
-#define	FR_CHANNEL_MTU	1500		/* unfragmented logical channel MTU */
-
-/* Q.922 frame types */
-#define	Q922_UI		0x03		/* Unnumbered Info frame */
-#define	Q922_XID	0xAF		
-
-/* DLCI configured or not */
-#define DLCI_NOT_CONFIGURED	0x00
-#define DLCI_CONFIG_PENDING	0x01
-#define DLCI_CONFIGURED		0x02
-
-/* CIR enabled or not */
-#define CIR_ENABLED	0x00
-#define CIR_DISABLED	0x01
-
-#define FRAME_RELAY_API 1
-#define MAX_BH_BUFF	10
-
-/* For handle_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 channel-specific data.
- */
-typedef struct fr_channel
-{
-	wanpipe_common_t common;
-	char name[WAN_IFNAME_SZ+1];	/* interface name, ASCIIZ */
-	unsigned dlci_configured  ;	/* check whether configured or not */
-	unsigned cir_status;		/* check whether CIR enabled or not */
-	unsigned dlci;			/* logical channel number */
-	unsigned cir;			/* committed information rate */
-	unsigned bc;			/* committed burst size */
-	unsigned be;			/* excess burst size */
-	unsigned mc;			/* multicast support on or off */
-	unsigned tx_int_status;		/* Transmit Interrupt Status */	
-	unsigned short pkt_length;	/* Packet Length */
-	unsigned long router_start_time;/* Router start time in seconds */
-	unsigned long tick_counter;	/* counter for transmit time out */
-	char dev_pending_devtint;	/* interface pending dev_tint() */
-	void *dlci_int_interface;	/* pointer to the DLCI Interface */ 
-	unsigned long IB_addr;		/* physical address of Interface Byte */
-	unsigned long state_tick;	/* time of the last state change */
-	unsigned char enable_IPX;	/* Enable/Disable the use of IPX */
-	unsigned long network_number;	/* Internal Network Number for IPX*/
-	sdla_t *card;			/* -> owner */
-	unsigned route_flag;		/* Add/Rem dest addr in route tables */
-	unsigned inarp;			/* Inverse Arp Request status */ 
-	long inarp_ready;		/* Ready to send requests */
-	int inarp_interval;		/* Time between InArp Requests */
-	unsigned long inarp_tick;	/* InArp jiffies tick counter */
-	long interface_down;		/* Bring interface down on disconnect */
-	struct net_device_stats ifstats;	/* interface statistics */
-	if_send_stat_t drvstats_if_send;
-        rx_intr_stat_t drvstats_rx_intr;
-        pipe_mgmt_stat_t drvstats_gen;
-	unsigned long router_up_time;
-
-	unsigned short transmit_length;
-	struct sk_buff *delay_skb;
-
-	bh_data_t *bh_head;	  	  /* Circular buffer for chdlc_bh */
-	unsigned long  tq_working;
-	volatile int  bh_write;
-	volatile int  bh_read;
-	atomic_t  bh_buff_used;
-
-	/* Polling task queue. Each interface
-         * has its own task queue, which is used
-         * to defer events from the interrupt */
-	struct work_struct fr_poll_work;
-	struct timer_list fr_arp_timer;
-
-	u32 ip_local;
-	u32 ip_remote;
-	long config_dlci;
-	long unconfig_dlci;
-
-	/* Whether this interface should be setup as a gateway.
-	 * Used by dynamic route setup code */
-	u8  gateway;
-
-	/* True interface type */
-	u8 true_if_encoding;
-	u8 fr_header[FR_HEADER_LEN];
-	char fr_header_len;
-
-} fr_channel_t;
-
-/* Route Flag options */
-#define NO_ROUTE	0x00
-#define ADD_ROUTE 	0x01
-#define ROUTE_ADDED	0x02
-#define REMOVE_ROUTE 	0x03
-#define ARP_REQ		0x04
-
-/* inarp options */
-#define INARP_NONE		0x00
-#define INARP_REQUEST		0x01
-#define INARP_CONFIGURED	0x02
-
-/* reasons for enabling the timer interrupt on the adapter */
-#define TMR_INT_ENABLED_UDP   	0x01
-#define TMR_INT_ENABLED_UPDATE 	0x02
-#define TMR_INT_ENABLED_ARP	0x04
-#define TMR_INT_ENABLED_UPDATE_STATE 	0x08
-#define TMR_INT_ENABLED_CONFIG	0x10
-#define TMR_INT_ENABLED_UNCONFIG	0x20
-
-
-typedef struct dlci_status
-{
-	unsigned short dlci	PACKED;
-	unsigned char state	PACKED;
-} dlci_status_t;
-
-typedef struct dlci_IB_mapping
-{
-	unsigned short dlci		PACKED;
-	unsigned long  addr_value	PACKED;
-} dlci_IB_mapping_t;
-
-/* This structure is used for DLCI list Tx interrupt mode.  It is used to
-   enable interrupt bit and set the packet length for transmission
- */
-typedef struct fr_dlci_interface 
-{
-	unsigned char gen_interrupt	PACKED;
-	unsigned short packet_length	PACKED;
-	unsigned char reserved		PACKED;
-} fr_dlci_interface_t; 
-
-/* variable for keeping track of enabling/disabling FT1 monitor status */
-static int rCount = 0;
-
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-/* variable for keeping track of number of interrupts generated during 
- * interrupt test routine 
- */
-static int Intr_test_counter;
-
-/****** Function Prototypes *************************************************/
-
-/* WAN link driver entry points. These are called by the WAN router module. */
-static int update(struct wan_device *wandev);
-static int new_if(struct wan_device *wandev, struct net_device *dev,
-		  wanif_conf_t *conf);
-static int del_if(struct wan_device *wandev, struct net_device *dev);
-static void disable_comm (sdla_t *card);
-
-/* WANPIPE-specific entry points */
-static int wpf_exec(struct sdla *card, void *u_cmd, void *u_data);
-
-/* Network device interface */
-static int if_init(struct net_device *dev);
-static int if_open(struct net_device *dev);
-static int if_close(struct net_device *dev);
-
-static void if_tx_timeout(struct net_device *dev);
-
-static int if_rebuild_hdr (struct sk_buff *skb);
-
-static int if_send(struct sk_buff *skb, struct net_device *dev);
-static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
-                                struct sk_buff *skb);
-static struct net_device_stats *if_stats(struct net_device *dev);
-
-/* Interrupt handlers */
-static void fr_isr(sdla_t *card);
-static void rx_intr(sdla_t *card);
-static void tx_intr(sdla_t *card);
-static void timer_intr(sdla_t *card);
-static void spur_intr(sdla_t *card);
-
-/* Frame relay firmware interface functions */
-static int fr_read_version(sdla_t *card, char *str);
-static int fr_configure(sdla_t *card, fr_conf_t *conf);
-static int fr_dlci_configure(sdla_t *card, fr_dlc_conf_t *conf, unsigned dlci);
-static int fr_init_dlci (sdla_t *card, fr_channel_t *chan);
-static int fr_set_intr_mode (sdla_t *card, unsigned mode, unsigned mtu, unsigned short timeout);
-static int fr_comm_enable(sdla_t *card);
-static void fr_comm_disable(sdla_t *card);
-static int fr_get_err_stats(sdla_t *card);
-static int fr_get_stats(sdla_t *card);
-static int fr_add_dlci(sdla_t *card, int dlci);
-static int fr_activate_dlci(sdla_t *card, int dlci);
-static int fr_delete_dlci (sdla_t* card, int dlci);
-static int fr_issue_isf(sdla_t *card, int isf);
-static int fr_send(sdla_t *card, int dlci, unsigned char attr, int len,
-	void *buf);
-static int fr_send_data_header(sdla_t *card, int dlci, unsigned char attr, int len,
-	void *buf,unsigned char hdr_len);
-static unsigned int fr_send_hdr(sdla_t *card, int dlci, unsigned int offset);
-
-static int check_dlci_config (sdla_t *card, fr_channel_t *chan);
-static void initialize_rx_tx_buffers (sdla_t *card);
-
-
-/* Firmware asynchronous event handlers */
-static int fr_event(sdla_t *card, int event, fr_mbox_t *mbox);
-static int fr_modem_failure(sdla_t *card, fr_mbox_t *mbox);
-static int fr_dlci_change(sdla_t *card, fr_mbox_t *mbox);
-
-/* Miscellaneous functions */
-static int update_chan_state(struct net_device *dev);
-static void set_chan_state(struct net_device *dev, int state);
-static struct net_device *find_channel(sdla_t *card, unsigned dlci);
-static int is_tx_ready(sdla_t *card, fr_channel_t *chan);
-static unsigned int dec_to_uint(unsigned char *str, int len);
-static int reply_udp( unsigned char *data, unsigned int mbox_len );
-
-static int intr_test( sdla_t* card );
-static void init_chan_statistics( fr_channel_t* chan );
-static void init_global_statistics( sdla_t* card );
-static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan );
-static int setup_for_delayed_transmit(struct net_device* dev,
-				      struct sk_buff *skb);
-
-struct net_device *move_dev_to_next(sdla_t *card, struct net_device *dev);
-static int check_tx_status(sdla_t *card, struct net_device *dev);
-
-/* Frame Relay Socket API */
-static void trigger_fr_bh (fr_channel_t *);
-static void fr_bh(struct net_device *dev);
-static int fr_bh_cleanup(struct net_device *dev);
-static int bh_enqueue(struct net_device *dev, struct sk_buff *skb);
-
-static void trigger_fr_poll(struct net_device *dev);
-static void fr_poll(struct net_device *dev);
-//static void add_gateway(struct net_device *dev);
-
-static void trigger_unconfig_fr(struct net_device *dev);
-static void unconfig_fr (sdla_t *);
-
-static void trigger_config_fr (sdla_t *);
-static void config_fr (sdla_t *);
-
-
-/* Inverse ARP and Dynamic routing functions */
-int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device *dev);
-int is_arp(void *buf);
-int send_inarp_request(sdla_t *card, struct net_device *dev);
-
-static void trigger_fr_arp(struct net_device *dev);
-static void fr_arp (unsigned long data);
-
-
-/* Udp management functions */
-static int process_udp_mgmt_pkt(sdla_t *card);
-static int udp_pkt_type( struct sk_buff *skb, sdla_t *card );
-static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card,
-                                struct sk_buff *skb, int dlci);
-
-/* 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);
-
-/* Lock Functions: SMP supported */
-void 	s508_s514_unlock(sdla_t *card, unsigned long *smp_flags);
-void 	s508_s514_lock(sdla_t *card, unsigned long *smp_flags);
-
-unsigned short calc_checksum (char *, int);
-static int setup_fr_header(struct sk_buff *skb,
-			   struct net_device* dev, char op_mode);
-
-
-/****** Public Functions ****************************************************/
-
-/*============================================================================
- * Frame relay protocol initialization routine.
- *
- * This routine is called by the main WANPIPE module during setup.  At this
- * point adapter is completely initialized and 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 wpf_init(sdla_t *card, wandev_conf_t *conf)
-{
-
-	int err;
-	fr508_flags_t* flags;
-
-	union
-	{
-		char str[80];
-		fr_conf_t cfg;
-	} u;
-
-	fr_buf_info_t* buf_info;
-	int i;
-
-
-	printk(KERN_INFO "\n");
-
-	/* Verify configuration ID */
-	if (conf->config_id != WANCONFIG_FR) {
-		
-		printk(KERN_INFO "%s: invalid configuration ID %u!\n",
-			card->devname, conf->config_id);
-		return -EINVAL;
-	
-	}
-
-	/* Initialize protocol-specific fields of adapter data space */
-	switch (card->hw.fwid) {
-	
-		case SFID_FR508:
-			card->mbox  = (void*)(card->hw.dpmbase + 
-					FR508_MBOX_OFFS);
-			card->flags = (void*)(card->hw.dpmbase + 
-					FR508_FLAG_OFFS);
-			if(card->hw.type == SDLA_S514) {
-				card->mbox += FR_MB_VECTOR;
-                                card->flags += FR_MB_VECTOR;
-			}
-                        card->isr = &fr_isr;
-			break;
-
-		default:
-			return -EINVAL;
-	}
-
-	flags = card->flags;
-
-	/* 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 (fr_read_version(card, NULL) || fr_read_version(card, u.str))
-		return -EIO;
-
-	printk(KERN_INFO "%s: running frame relay firmware v%s\n",
-		card->devname, u.str);
-
-	/* Adjust configuration */
-	conf->mtu += FR_HEADER_LEN;
-	conf->mtu = (conf->mtu >= MIN_LGTH_FR_DATA_CFG) ?
-			min_t(unsigned int, conf->mtu, FR_MAX_NO_DATA_BYTES_IN_FRAME) :
-                        FR_CHANNEL_MTU + FR_HEADER_LEN;
-     
-	conf->bps = min_t(unsigned int, conf->bps, 2048000);
-
-	/* Initialze the configuration structure sent to the board to zero */
-	memset(&u.cfg, 0, sizeof(u.cfg));
-
-	memset(card->u.f.dlci_to_dev_map, 0, sizeof(card->u.f.dlci_to_dev_map));
- 	
-	/* Configure adapter firmware */
-
-	u.cfg.mtu	= conf->mtu;
-	u.cfg.kbps	= conf->bps / 1000;
-
-    	u.cfg.cir_fwd = u.cfg.cir_bwd = 16;
-        u.cfg.bc_fwd  = u.cfg.bc_bwd = 16;
-	
-	u.cfg.options	= 0x0000;
-	printk(KERN_INFO "%s: Global CIR enabled by Default\n", card->devname);
-	
-	switch (conf->u.fr.signalling) {
-
-		case WANOPT_FR_ANSI:
-			u.cfg.options = 0x0000; 
-			break;		
-	
-		case WANOPT_FR_Q933:	
-			u.cfg.options |= 0x0200; 
-			break;
-	
-		case WANOPT_FR_LMI:	
-			u.cfg.options |= 0x0400; 
-			break;
-
-		case WANOPT_NO:
-			u.cfg.options |= 0x0800; 
-			break;
-		default:
-			printk(KERN_INFO "%s: Illegal Signalling option\n",
-					card->wandev.name);
-			return -EINVAL;
-	}
-
-
-	card->wandev.signalling = conf->u.fr.signalling;
-
-	if (conf->station == WANOPT_CPE) {
-
-
-		if (conf->u.fr.signalling == WANOPT_NO){
-			printk(KERN_INFO 
-				"%s: ERROR - For NO signalling, station must be set to Node!",
-				 	 card->devname);
-			return -EINVAL;
-		}
-
-		u.cfg.station = 0;
-		u.cfg.options |= 0x8000;	/* auto config DLCI */
-		card->u.f.dlci_num  = 0;
-	
-	} else {
-
-		u.cfg.station = 1;	/* switch emulation mode */
-
-		/* For switch emulation we have to create a list of dlci(s)
-		 * that will be sent to be global SET_DLCI_CONFIGURATION 
-		 * command in fr_configure() routine. 
-		 */
-
-		card->u.f.dlci_num  = min_t(unsigned int, max_t(unsigned int, conf->u.fr.dlci_num, 1), 100);
-	
-		for ( i = 0; i < card->u.f.dlci_num; i++) {
-
-			card->u.f.node_dlci[i] = (unsigned short) 
-				conf->u.fr.dlci[i] ? conf->u.fr.dlci[i] : 16;
-	
-		}
-	}
-
-	if (conf->clocking == WANOPT_INTERNAL)
-		u.cfg.port |= 0x0001;
-
-	if (conf->interface == WANOPT_RS232)
-		u.cfg.port |= 0x0002;
-
-	if (conf->u.fr.t391)
-		u.cfg.t391 = min_t(unsigned int, conf->u.fr.t391, 30);
-	else
-		u.cfg.t391 = 5;
-
-	if (conf->u.fr.t392)
-		u.cfg.t392 = min_t(unsigned int, conf->u.fr.t392, 30);
-	else
-		u.cfg.t392 = 15;
-
-	if (conf->u.fr.n391)
-		u.cfg.n391 = min_t(unsigned int, conf->u.fr.n391, 255);
-	else
-		u.cfg.n391 = 2;
-
-	if (conf->u.fr.n392)
-		u.cfg.n392 = min_t(unsigned int, conf->u.fr.n392, 10);
-	else
-		u.cfg.n392 = 3;	
-
-	if (conf->u.fr.n393)
-		u.cfg.n393 = min_t(unsigned int, conf->u.fr.n393, 10);
-	else
-		u.cfg.n393 = 4;
-
-	if (fr_configure(card, &u.cfg))
-		return -EIO;
-
-	if (card->hw.type == SDLA_S514) {
-	
-                buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR +
-			FR508_RXBC_OFFS);
-
-                card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase);
-
-                card->u.f.rxmb_base =
-                        (void*)(buf_info->rse_base + card->hw.dpmbase); 
-
-                card->u.f.rxmb_last =
-                        (void*)(buf_info->rse_base +
-                        (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) +
-                        card->hw.dpmbase);
-	}else{	
-		buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS);
-
-		card->rxmb = (void*)(buf_info->rse_next -
-			FR_MB_VECTOR + card->hw.dpmbase);
-		
-		card->u.f.rxmb_base =
-			(void*)(buf_info->rse_base -
-			FR_MB_VECTOR + card->hw.dpmbase);
-		
-		card->u.f.rxmb_last =
-			(void*)(buf_info->rse_base +
-			(buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) -
-			FR_MB_VECTOR + card->hw.dpmbase);
-	}
-
-	card->u.f.rx_base = buf_info->buf_base;
-	card->u.f.rx_top  = buf_info->buf_top;
-
-	card->u.f.tx_interrupts_pending = 0;
-
-	card->wandev.mtu	= conf->mtu;
-	card->wandev.bps	= conf->bps;
-	card->wandev.interface	= conf->interface;
-	card->wandev.clocking	= conf->clocking;
-	card->wandev.station	= conf->station;
-	card->poll		= NULL; 
-	card->exec		= &wpf_exec;
-	card->wandev.update	= &update;
-	card->wandev.new_if	= &new_if;
-	card->wandev.del_if	= &del_if;
-	card->wandev.state	= WAN_DISCONNECTED;
-	card->wandev.ttl	= conf->ttl;
-        card->wandev.udp_port 	= conf->udp_port;       
-	card->disable_comm	= &disable_comm;	
-	card->u.f.arp_dev 	= NULL;
-
-	/* Intialize global statistics for a card */
-	init_global_statistics( card );
-
-        card->TracingEnabled          = 0;
-
-	/* Interrupt Test */
-	Intr_test_counter = 0;
-	card->intr_mode = INTR_TEST_MODE;
-	err = intr_test( card );
-
-	printk(KERN_INFO "%s: End of Interrupt Test rc=0x%x  count=%i\n",
-			card->devname,err,Intr_test_counter); 
-	
-	if (err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
-		printk(KERN_ERR "%s: Interrupt Test Failed, Counter: %i\n", 
-			card->devname, Intr_test_counter);
-		printk(KERN_ERR "Please choose another interrupt\n");
-		err = -EIO;
-		return err;
-	}
-
-	printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n",
-			card->devname, Intr_test_counter);
-
-
-	/* Apr 28 2000. Nenad Corbic
-	 * Enable commnunications here, not in if_open or new_if, since
-         * interfaces come down when the link is disconnected. 
-         */
-	 
-	/* If you enable comms and then set ints, you get a Tx int as you
-	 * perform the SET_INT_TRIGGERS command. So, we only set int
-	 * triggers and then adjust the interrupt mask (to disable Tx ints)
-	 * before enabling comms. 
-	 */	
-        if (fr_set_intr_mode(card, (FR_INTR_RXRDY | FR_INTR_TXRDY |
-		FR_INTR_DLC | FR_INTR_TIMER | FR_INTR_TX_MULT_DLCIs) ,
-		card->wandev.mtu, 0)) {
-		return -EIO;
-	}
-
-	flags->imask &= ~(FR_INTR_TXRDY | FR_INTR_TIMER);
- 
-	if (fr_comm_enable(card)) {
-		return -EIO;
-	}	
-	wanpipe_set_state(card, WAN_CONNECTED);
-	spin_lock_init(&card->u.f.if_send_lock);
-	
-	printk(KERN_INFO "\n");
-
-        return 0;
-}
-
-/******* WAN Device Driver Entry Points *************************************/
-
-/*============================================================================
- * Update device status & statistics.
- */
-static int update(struct wan_device* wandev)
-{
-	volatile sdla_t* card;
-	unsigned long timeout;
-	fr508_flags_t* flags;
-
-	/* sanity checks */
-	if ((wandev == NULL) || (wandev->private == NULL))
-		return -EFAULT;
-
-	if (wandev->state == WAN_UNCONFIGURED)
-		return -ENODEV;
-
-	card = wandev->private;
-	flags = card->flags;
-
-
-	card->u.f.update_comms_stats = 1;
-	card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
-	flags->imask |= FR_INTR_TIMER;
-       	timeout = jiffies;
-       	for(;;) {
-		if(card->u.f.update_comms_stats == 0)
-			break;
-                if (time_after(jiffies, timeout + 1 * HZ)){
-    			card->u.f.update_comms_stats = 0;
- 			return -EAGAIN;
-		}
-        }
-
-	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(struct wan_device* wandev, struct net_device* dev,
-		  wanif_conf_t* conf)
-{
-	sdla_t* card = wandev->private;
-	fr_channel_t* chan;
-	int dlci = 0;
-	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(fr_channel_t), GFP_KERNEL);
-
-	if (chan == NULL)
-		return -ENOMEM;
-
-	memset(chan, 0, sizeof(fr_channel_t));
-	strcpy(chan->name, conf->name);
-	chan->card = card;
-
-	/* verify media address */
-	if (isdigit(conf->addr[0])) {
-
-		dlci = dec_to_uint(conf->addr, 0);
-
-		if (dlci && (dlci <= HIGHEST_VALID_DLCI)) {
-		
-			chan->dlci = dlci;
-		
-		} else {
-		
-			printk(KERN_ERR
-				"%s: Invalid DLCI %u on interface %s!\n",
-				wandev->name, dlci, chan->name);
-			err = -EINVAL;
-		}
-
-	} else {
-		printk(KERN_ERR
-			"%s: Invalid media address on interface %s!\n",
-			wandev->name, chan->name);
-		err = -EINVAL;
-	}
-
-	if ((chan->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){
-		printk(KERN_INFO 
-			"%s: Enabling, true interface type encoding.\n",
-			card->devname);
-	}
-	
-
-
-    /* Setup wanpipe as a router (WANPIPE) even if it is
-	 * a bridged DLCI, or as an API 
-	 */
-        if (strcmp(conf->usedby, "WANPIPE")  == 0  || 
-	    strcmp(conf->usedby, "BRIDGE")   == 0  ||
-	    strcmp(conf->usedby, "BRIDGE_N") == 0){
-		
-		if(strcmp(conf->usedby, "WANPIPE") == 0){
-			chan->common.usedby = WANPIPE;
-			
-	                printk(KERN_INFO "%s: Running in WANPIPE mode.\n", 
-					card->devname);
-			
-		}else if(strcmp(conf->usedby, "BRIDGE") == 0){
-			
-			chan->common.usedby = BRIDGE;
-			
-			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)
- *		non-0	packet may be re-transmitted (tbusy must be set)
- *
- * Notes:
- * 1. This routine is called either by the protocol stack or by the "net
- *    bottom half" (with interrupts enabled).
- * 
- * 2. Using netif_start_queue() and netif_stop_queue()
- *    will inhibit further transmit requests from the protocol stack 
- *    and can be used for flow control with protocol layer.
- */
-static int if_send(struct sk_buff* skb, struct net_device* dev)
-{
-    	fr_channel_t* chan = dev->priv;
-    	sdla_t* card = chan->card;
-        int err;
-    	unsigned char *sendpacket;
-    	fr508_flags_t* adptr_flags = card->flags;
-	int udp_type;
-	long delay_tx_queued = 0;
-	unsigned long smp_flags=0;
-	unsigned char attr = 0;
-
-	chan->drvstats_if_send.if_send_entry++;
-
-	netif_stop_queue(dev);
-	
-        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);
-		chan->drvstats_if_send.if_send_skb_null ++;
-
-		netif_wake_queue(dev);
-		return 0;
-	}
-
-	/* If a peripheral task is running just drop packets */
-	if (test_bit(PERI_CRIT, &card->wandev.critical)){
-		
-		printk(KERN_INFO "%s: Critical in if_send(): Peripheral running!\n",
-				card->devname);
-		
-		dev_kfree_skb_any(skb);
-		netif_start_queue(dev);
-		return 0;
-	}
-
-	/* We must set the 'tbusy' flag if we already have a packet queued for
-	   transmission in the transmit interrupt handler. However, we must
-	   ensure that the transmit interrupt does not reset the 'tbusy' flag
-	   just before we set it, as this will result in a "transmit timeout".
-	*/
-	set_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical);
-        if(chan->transmit_length) {
-		netif_stop_queue(dev);
-		chan->tick_counter = jiffies;
- 		clear_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical);
-		return 1;
-	}
-       	clear_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical);
- 
-	/* Move the if_header() code to here. By inserting frame
-	 * relay header in if_header() we would break the
-	 * tcpdump and other packet sniffers */
-	chan->fr_header_len = setup_fr_header(skb,dev,chan->common.usedby);
-	if (chan->fr_header_len < 0 ){
-		++chan->ifstats.tx_dropped;
-		++card->wandev.stats.tx_dropped;
-		
-		dev_kfree_skb_any(skb);
-		netif_start_queue(dev);	
-		return 0;
-	}
-
-	sendpacket = skb->data;
-
-	udp_type = udp_pkt_type(skb, card);
-
-        if(udp_type != UDP_INVALID_TYPE) {
-		if(store_udp_mgmt_pkt(udp_type, UDP_PKT_FRM_STACK, card, skb,
-                        chan->dlci)) {
-                        adptr_flags->imask |= FR_INTR_TIMER;
-                        if (udp_type == UDP_FPIPE_TYPE){
-                                chan->drvstats_if_send.
-					if_send_PIPE_request ++;
-			}
-                }
-		netif_start_queue(dev);
-		return 0;
-	}
-
-	//FIXME: can we do better than sendpacket[2]?
-  	if ((chan->common.usedby == WANPIPE) && (sendpacket[2] == 0x45)) {
-		
-               	/* check to see if the source IP address is a broadcast or */
-                /* multicast IP address */
-                if(chk_bcast_mcast_addr(card, dev, skb)){
-            		++chan->ifstats.tx_dropped;
-			++card->wandev.stats.tx_dropped;
-                	dev_kfree_skb_any(skb);
-			netif_start_queue(dev);
-			return 0;
-		}
-	}
-
-	
-	/* Lock the S514/S508 card: SMP Supported */
-    	s508_s514_lock(card,&smp_flags);
-
-	if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
-		
-		chan->drvstats_if_send.if_send_critical_non_ISR ++;
-		chan->ifstats.tx_dropped ++;
-		printk(KERN_INFO "%s Critical in IF_SEND: if_send() already running!\n", 
-				card->devname);
-		goto if_send_start_and_exit;
-	}
-	
-	/* API packet check: minimum packet size must be greater than 
-	 * 16 byte API header */
-	if((chan->common.usedby == API) && (skb->len <= sizeof(api_tx_hdr_t))) {
-		++chan->ifstats.tx_dropped;
-		++card->wandev.stats.tx_dropped;
-	    
-		
-		goto if_send_start_and_exit;
-
- 	}else{
-		/* During API transmission, get rid of the API header */
-		if (chan->common.usedby == API) {
-			api_tx_hdr_t* api_tx_hdr;
-			api_tx_hdr = (api_tx_hdr_t*)&skb->data[0x00];
-			attr = api_tx_hdr->attr;
-			skb_pull(skb,sizeof(api_tx_hdr_t));
-		}
-	}
-
-	if (card->wandev.state != WAN_CONNECTED) {
-		chan->drvstats_if_send.if_send_wan_disconnected ++;
-		++chan->ifstats.tx_dropped;
-        	++card->wandev.stats.tx_dropped;
-	
-	} else if (chan->common.state != WAN_CONNECTED) {
-		chan->drvstats_if_send.if_send_dlci_disconnected ++;
-
-		/* Update the DLCI state in timer interrupt */
-		card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UPDATE_STATE;	
-		adptr_flags->imask |= FR_INTR_TIMER;
-
-        	++chan->ifstats.tx_dropped;
-        	++card->wandev.stats.tx_dropped;
-		
-	} else if (!is_tx_ready(card, chan)) {
-		/* No tx buffers available, store for delayed transmit */
-		if (!setup_for_delayed_transmit(dev, skb)){
-			set_bit(1,&delay_tx_queued);
-		}
-		chan->drvstats_if_send.if_send_no_bfrs++;
-		
-	} else if (!skb->protocol) {
-		/* No protocols drop packet */
-		chan->drvstats_if_send.if_send_protocol_error ++;
-		++card->wandev.stats.tx_errors;
-	
-	} else if (test_bit(ARP_CRIT,&card->wandev.critical)){
-		/* We are trying to send an ARP Packet, block IP data until
-		 * ARP is sent */
-		++chan->ifstats.tx_dropped;
-        	++card->wandev.stats.tx_dropped;
-		
-	} else {
-		//FIXME: IPX is not implemented in this version of Frame Relay ?
-		if((chan->common.usedby == WANPIPE) &&
-		 	sendpacket[1] == 0x00 &&
-		    	sendpacket[2] == 0x80 &&
-		    	sendpacket[6] == 0x81 &&
-		    	sendpacket[7] == 0x37) {
-			
-			if( chan->enable_IPX ) {
-				switch_net_numbers(sendpacket, 
-						chan->network_number, 0);
-			} else {
-				//FIXME: Take this out when IPX is fixed 
-				printk(KERN_INFO 
-				"%s: WARNING: Unsupported IPX data in send, packet dropped\n",
-					card->devname);
-			}
-			
-		}else{
-        		err = fr_send_data_header(card, chan->dlci, attr, skb->len, skb->data, chan->fr_header_len);
-			if (err) {
-				switch(err) {
-				case FRRES_CIR_OVERFLOW:
-				case FRRES_BUFFER_OVERFLOW:
-                			if (!setup_for_delayed_transmit(dev, skb)){
-						set_bit(1,&delay_tx_queued);
-					}
-           				chan->drvstats_if_send.
-						if_send_adptr_bfrs_full ++;
-					break;
-					
-				case FRRES_TOO_LONG:
-					if (net_ratelimit()){
-						printk(KERN_INFO 
-						"%s: Error: Frame too long, transmission failed %i\n",
-						 card->devname, (unsigned int)skb->len);
-					}
-					/* Drop down to default */
-				default:
-					chan->drvstats_if_send.
-						if_send_dlci_disconnected ++;
-        				++chan->ifstats.tx_dropped;
-        				++card->wandev.stats.tx_dropped;
-					break;
-				}
-			} else {
-				chan->drvstats_if_send.
-					if_send_bfr_passed_to_adptr++;
-				++chan->ifstats.tx_packets;
-				++card->wandev.stats.tx_packets;
-				
-                                chan->ifstats.tx_bytes += skb->len;
-                                card->wandev.stats.tx_bytes += skb->len;
-				dev->trans_start = jiffies;
-			}
-		}
-	}
-
-if_send_start_and_exit:
-
-	netif_start_queue(dev);
-	
-	/* If we queued the packet for transmission, we must not
-	 * deallocate it. The packet is unlinked from the IP stack
-	 * not copied. Therefore, we must keep the original packet */
-	if (!test_bit(1,&delay_tx_queued)) {
-                dev_kfree_skb_any(skb);
-	}else{
-		adptr_flags->imask |= FR_INTR_TXRDY;
-		card->u.f.tx_interrupts_pending ++;
-	}
-
-        clear_bit(SEND_CRIT, (void*)&card->wandev.critical);
-
-	s508_s514_unlock(card,&smp_flags);
-
-	return 0;
-}
-
-
-
-/*============================================================================
- * Setup so that a frame can be transmitted on the occurrence of a transmit
- * interrupt.
- */
-static int setup_for_delayed_transmit(struct net_device* dev,
-				      struct sk_buff *skb)
-{
-        fr_channel_t* chan = dev->priv;
-        sdla_t* card = chan->card;
-        fr_dlci_interface_t* dlci_interface;
-	int len = skb->len;
-
-	/* Check that the dlci is properly configured,
-         * before using tx interrupt */
-	if (!chan->dlci_int_interface){
-		if (net_ratelimit()){ 
-			printk(KERN_INFO 
-				"%s: ERROR on DLCI %i: Not configured properly !\n",
-					card->devname, chan->dlci);
-			printk(KERN_INFO "%s: Please contact Sangoma Technologies\n",
-					card->devname);
-		}
-		return 1;
-	}
-		
-	dlci_interface = chan->dlci_int_interface;
-
-        if(chan->transmit_length) {
-                printk(KERN_INFO "%s: Big mess in setup_for_del...\n",
-				card->devname);
-                return 1;
-        }
-
-	if(len > FR_MAX_NO_DATA_BYTES_IN_FRAME) {
-		//FIXME: increment some statistic */
-		return 1;
-	}
-
-        chan->transmit_length = len;
-	chan->delay_skb = skb;
-        
-        dlci_interface->gen_interrupt |= FR_INTR_TXRDY;
-        dlci_interface->packet_length = len;
-
-	/* Turn on TX interrupt at the end of if_send */
-	return 0;
-}
-
-
-/*============================================================================
- * Check to see if the packet to be transmitted contains a broadcast or
- * multicast source IP address.
- * Return 0 if not broadcast/multicast address, otherwise return 1.
- */
-
-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;
-        struct in_device *in_dev;
-        fr_channel_t* chan = dev->priv;
- 
-        /* read the IP source address from the outgoing packet */
-        src_ip_addr = *(u32 *)(skb->data + 14);
-
-        /* read the IP broadcast address for the device */
-        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;
-        }
-
-        /* 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((chan->mc == WANOPT_NO) && (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 nothing.
- */
-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;
-
-  
-	fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)data; 
-
-	/* Set length of packet */
-	len = //sizeof(fr_encap_hdr_t)+
-	      sizeof(ip_pkt_t)+ 
-	      sizeof(udp_pkt_t)+
-	      sizeof(wp_mgmt_t)+
-	      sizeof(cblock_t)+
-	      mbox_len;
- 
-
-	/* fill in UDP reply */
-	fr_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)+
-		     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);
-	fr_udp_pkt->udp_pkt.udp_length = temp;
-	 
-	/* swap UDP ports */
-	temp = fr_udp_pkt->udp_pkt.udp_src_port;
-	fr_udp_pkt->udp_pkt.udp_src_port = 
-			fr_udp_pkt->udp_pkt.udp_dst_port; 
-	fr_udp_pkt->udp_pkt.udp_dst_port = temp;
-
-
-
-	/* add UDP pseudo header */
-	temp = 0x1100;
-	*((unsigned short *)
-		(fr_udp_pkt->data+mbox_len+even_bound)) = temp;	
-	temp = (udp_length<<8)|(udp_length>>8);
-	*((unsigned short *)
-		(fr_udp_pkt->data+mbox_len+even_bound+2)) = temp;
-		 
-	/* calculate UDP checksum */
-	fr_udp_pkt->udp_pkt.udp_checksum = 0;
-
-	fr_udp_pkt->udp_pkt.udp_checksum = 
-		calc_checksum(&data[UDP_OFFSET/*+sizeof(fr_encap_hdr_t)*/],
-			      udp_length+UDP_OFFSET);
-
-	/* fill in IP length */
-	ip_length = udp_length + sizeof(ip_pkt_t);
-	temp = (ip_length<<8)|(ip_length>>8);
-	fr_udp_pkt->ip_pkt.total_length = temp;
-  
-	/* swap IP addresses */
-	ip_temp = fr_udp_pkt->ip_pkt.ip_src_address;
-	fr_udp_pkt->ip_pkt.ip_src_address = 
-				fr_udp_pkt->ip_pkt.ip_dst_address;
-	fr_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
-
-		 
-	/* fill in IP checksum */
-	fr_udp_pkt->ip_pkt.hdr_checksum = 0;
-	fr_udp_pkt->ip_pkt.hdr_checksum = 
-		calc_checksum(&data[/*sizeof(fr_encap_hdr_t)*/0],
-		      	      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;	
-}
-
-/*
-   If incoming is 0 (outgoing)- if the net numbers is ours make it 0
-   if incoming is 1 - if the net number is 0 make it ours 
-
-*/
-static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming)
-{
-	unsigned long pnetwork_number;
-
-	pnetwork_number = (unsigned long)((sendpacket[14] << 24) + 
-			  (sendpacket[15] << 16) + (sendpacket[16] << 8) + 
-			  sendpacket[17]);
-
-	if (!incoming) {
-		/* If the destination network number is ours, make it 0 */
-		if( pnetwork_number == network_number) {
-			sendpacket[14] = sendpacket[15] = sendpacket[16] = 
-					 sendpacket[17] = 0x00;
-		}
-	} else {
-		/* If the incoming network is 0, make it ours */
-		if( pnetwork_number == 0) {
-			sendpacket[14] = (unsigned char)(network_number >> 24);
-			sendpacket[15] = (unsigned char)((network_number & 
-					 0x00FF0000) >> 16);
-			sendpacket[16] = (unsigned char)((network_number & 
-					 0x0000FF00) >> 8);
-			sendpacket[17] = (unsigned char)(network_number & 
-					 0x000000FF);
-		}
-	}
-
-
-	pnetwork_number = (unsigned long)((sendpacket[26] << 24) + 
-			  (sendpacket[27] << 16) + (sendpacket[28] << 8) + 
-			  sendpacket[29]);
-
-	if( !incoming ) {
-		/* If the source network is ours, make it 0 */
-		if( pnetwork_number == network_number) {
-			sendpacket[26] = sendpacket[27] = sendpacket[28] = 
-					 sendpacket[29] = 0x00;
-		}
-	} else {
-		/* If the source network is 0, make it ours */
-		if( pnetwork_number == 0 ) {
-			sendpacket[26] = (unsigned char)(network_number >> 24);
-			sendpacket[27] = (unsigned char)((network_number & 
-					 0x00FF0000) >> 16);
-			sendpacket[28] = (unsigned char)((network_number & 
-					 0x0000FF00) >> 8);
-			sendpacket[29] = (unsigned char)(network_number & 
-					 0x000000FF);
-		}
-	}
-} /* switch_net_numbers */
-
-/*============================================================================
- * Get ethernet-style interface statistics.
- * Return a pointer to struct enet_statistics.
- */
-static struct net_device_stats *if_stats(struct net_device *dev)
-{
-	fr_channel_t* chan = dev->priv;
-	
-	if(chan == NULL)
-		return NULL;
-
-	return &chan->ifstats;
-}
-
-/****** Interrupt Handlers **************************************************/
-
-/*============================================================================
- * fr_isr:	S508 frame relay interrupt service routine.
- *
- * Description:
- *	Frame relay main interrupt service route. This
- *      function check the interrupt type and takes
- *      the appropriate action.
- */
-static void fr_isr (sdla_t* card)
-{
-	fr508_flags_t* flags = card->flags;
-	char *ptr = &flags->iflag;
-	int i,err;
-	fr_mbox_t* mbox = card->mbox;
-
-	/* This flag prevents nesting of interrupts.  See sdla_isr() routine
-         * in sdlamain.c.  */
-	card->in_isr = 1;
-	
-	++card->statistics.isr_entry;
-
-
-	/* All peripheral (configuraiton, re-configuration) events
-	 * take presidence over the ISR.  Thus, retrigger */
-	if (test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
-		++card->statistics.isr_already_critical;
-		goto fr_isr_exit;
-	}
-	
-        if(card->hw.type != SDLA_S514) {
-		if (test_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
-                        printk(KERN_INFO "%s: Critical while in ISR: If Send Running!\n",
-                                card->devname);
-			++card->statistics.isr_already_critical;
-			goto fr_isr_exit;
-		}
-	}
-
-	switch (flags->iflag) {
-
-                case FR_INTR_RXRDY:  /* receive interrupt */
-	    		++card->statistics.isr_rx;
-          		rx_intr(card);
-            		break;
-
-
-                case FR_INTR_TXRDY:  /* transmit interrupt */
-	    		++ card->statistics.isr_tx; 
-			tx_intr(card); 
-            		break;
-
-                case FR_INTR_READY:  	
-	    		Intr_test_counter++;
-			++card->statistics.isr_intr_test;
-	    		break;	
-
-                case FR_INTR_DLC: /* Event interrupt occurred */
-			mbox->cmd.command = FR_READ_STATUS;
-			mbox->cmd.length = 0;
-			err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-			if (err)
-				fr_event(card, err, mbox);
-			break;
-
-                case FR_INTR_TIMER:  /* Timer interrupt */
-			timer_intr(card);
-			break;
-	
-		default:
-	    		++card->statistics.isr_spurious;
-            		spur_intr(card);
-	    		printk(KERN_INFO "%s: Interrupt Type 0x%02X!\n", 
-				card->devname, flags->iflag);
-	    
-			printk(KERN_INFO "%s: ID Bytes = ",card->devname);
- 	    		for(i = 0; i < 8; i ++)
-				printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
-	   	 	printk(KERN_INFO "\n");	
-            
-			break;
-    	}
-
-fr_isr_exit:
-	
-	card->in_isr = 0;
-	flags->iflag = 0;
-	return;
-}
-
-
-
-/*===========================================================
- * rx_intr	Receive interrupt handler.
- *
- * Description
- * 	Upon receiveing an interrupt: 
- *	1. Check that the firmware is in sync with 
- *     	   the driver. 
- *      2. Find an appropriate network interface
- *         based on the received dlci number.
- *	3. Check that the netowrk interface exists
- *         and that it's setup properly.
- *	4. Copy the data into an skb buffer.
- *	5. Check the packet type and take
- *         appropriate acton: UPD, API, ARP or Data.
- */
-
-static void rx_intr (sdla_t* card)
-{
-	fr_rx_buf_ctl_t* frbuf = card->rxmb;
-	fr508_flags_t* flags = card->flags;
-	fr_channel_t* chan;
-	char *ptr = &flags->iflag;
-	struct sk_buff* skb;
-	struct net_device* dev;
-	void* buf;
-	unsigned dlci, len, offs, len_incl_hdr;
-	int i, udp_type;	
-
-
-	/* Check that firmware buffers are in sync */
-	if (frbuf->flag != 0x01) {
-
-		printk(KERN_INFO 
-			"%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", 
-			card->devname, (unsigned)frbuf, frbuf->flag);
-      
-		printk(KERN_INFO "%s: ID Bytes = ",card->devname);
- 		for(i = 0; i < 8; i ++)
-			printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
-		printk(KERN_INFO "\n");
-	
-		++card->statistics.rx_intr_corrupt_rx_bfr;
-
-		/* Bug Fix: Mar 6 2000
-                 * If we get a corrupted mailbox, it means that driver 
-                 * is out of sync with the firmware. There is no recovery.
-                 * If we don't turn off all interrupts for this card
-                 * the machine will crash. 
-                 */
-		printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
-		printk(KERN_INFO "Please contact Sangoma Technologies !\n");
-		fr_set_intr_mode(card, 0, 0, 0);	
-		return;
-	}
-
-	len  = frbuf->length;
-	dlci = frbuf->dlci;
-	offs = frbuf->offset;
-
-	/* Find the network interface for this packet */
-	dev = find_channel(card, dlci);
-   
-
-	/* Check that the network interface is active and
-         * properly setup */
-	if (dev == NULL) {
-   		if( net_ratelimit()) { 
-			printk(KERN_INFO "%s: received data on unconfigured DLCI %d!\n",
-                                                card->devname, dlci);
-		}
-		++card->statistics.rx_intr_on_orphaned_DLCI; 
-		++card->wandev.stats.rx_dropped;
-		goto rx_done;
-	}
-
-	if ((chan = dev->priv) == NULL){
-		if( net_ratelimit()) { 
-			printk(KERN_INFO "%s: received data on unconfigured DLCI %d!\n",
-                                                card->devname, dlci);
-		}
-		++card->statistics.rx_intr_on_orphaned_DLCI; 
-		++card->wandev.stats.rx_dropped;
-		goto rx_done;
-	}
-
-	skb = dev_alloc_skb(len); 
-
-	if (!netif_running(dev) || (skb == NULL)){
-
-		++chan->ifstats.rx_dropped;
-	
-		if(skb == NULL) {
-			if (net_ratelimit()) { 
-				printk(KERN_INFO 
-					"%s: no socket buffers available!\n", 
-						card->devname);
-			}
-			chan->drvstats_rx_intr.rx_intr_no_socket ++;
-		} 
-
-		if (!netif_running(dev)){
-			chan->drvstats_rx_intr.
-				rx_intr_dev_not_started ++;
-			if (skb){
-				dev_kfree_skb_any(skb);
-			}
-		}
-		goto rx_done;
-	}
-
-	/* Copy data from the board into the socket buffer */
-	if ((offs + len) > card->u.f.rx_top + 1) {
-		unsigned tmp = card->u.f.rx_top - offs + 1;
-
-		buf = skb_put(skb, tmp);
-		sdla_peek(&card->hw, offs, buf, tmp);
-		offs = card->u.f.rx_base;
-		len -= tmp;
-	}
-
-	buf = skb_put(skb, len);
-	sdla_peek(&card->hw, offs, buf, len);
-
-
-	/* We got the packet from the bard. 
-         * Check the packet type and take appropriate action */
-
-	udp_type = udp_pkt_type( skb, card );
-
-	if(udp_type != UDP_INVALID_TYPE) {
-
-		/* UDP Debug packet received, store the
-		 * packet and handle it in timer interrupt */
-
-		skb_pull(skb, 1); 
-		if (wanrouter_type_trans(skb, dev)){ 
-			if(store_udp_mgmt_pkt(udp_type,UDP_PKT_FRM_NETWORK,card,skb,dlci)){
-
-				flags->imask |= FR_INTR_TIMER;
-
-				if (udp_type == UDP_FPIPE_TYPE){
-					++chan->drvstats_rx_intr.rx_intr_PIPE_request;
-				}
-			}
-		}
-
-	}else if (chan->common.usedby == API) {
-
-		/* We are in API mode. 
-                 * Add an API header to the RAW packet
-                 * and queue it into a circular buffer.
-                 * Then kick the fr_bh() bottom half handler */
-
-		api_rx_hdr_t* api_rx_hdr;
-		chan->drvstats_rx_intr.rx_intr_bfr_passed_to_stack ++;
-		chan->ifstats.rx_packets ++;
-		card->wandev.stats.rx_packets ++;
-
-		chan->ifstats.rx_bytes += skb->len;
-		card->wandev.stats.rx_bytes += skb->len;
-
-		skb_push(skb, sizeof(api_rx_hdr_t));
-		api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00];
-		api_rx_hdr->attr = frbuf->attr;
-		api_rx_hdr->time_stamp = frbuf->tmstamp;
-
-		skb->protocol = htons(ETH_P_IP);
-		skb->mac.raw  = skb->data;
-		skb->dev      = dev;
-		skb->pkt_type = WAN_PACKET_DATA;
-
-		bh_enqueue(dev, skb);
-
-		trigger_fr_bh(chan);
-
-	}else if (handle_IPXWAN(skb->data,chan->name,chan->enable_IPX, chan->network_number)){
-
-		//FIXME: Frame Relay IPX is not supported, Yet !
-		//if (chan->enable_IPX) {
-		//	fr_send(card, dlci, 0, skb->len,skb->data);
-		//}
-		dev_kfree_skb_any(skb);
-
-	} else if (is_arp(skb->data)) {
-
-		/* ARP support enabled Mar 16 2000 
-		 * Process incoming ARP reply/request, setup
-		 * dynamic routes. */ 
-
-		if (process_ARP((arphdr_1490_t *)skb->data, card, dev)) {
-			if (net_ratelimit()){  
-				printk (KERN_INFO 
-				   "%s: Error processing ARP Packet.\n", 
-					card->devname);
-			}
-		}
-		dev_kfree_skb_any(skb);
-
-	} else if (skb->data[0] != 0x03) {
-
-		if (net_ratelimit()) { 
-			printk(KERN_INFO "%s: Non IETF packet discarded.\n", 
-				card->devname);
-		}
-		dev_kfree_skb_any(skb);
-
-	} else {
-
-		len_incl_hdr = skb->len;
-		/* Decapsulate packet and pass it up the
-		   protocol stack */
-		skb->dev = dev;
-		
-		if (chan->common.usedby == BRIDGE || chan->common.usedby == BRIDGE_NODE){
-		
-			/* Make sure it's an Ethernet frame, otherwise drop it */
-			if (!memcmp(skb->data, "\x03\x00\x80\x00\x80\xC2\x00\x07", 8)) {
-				skb_pull(skb, 8);
-				skb->protocol=eth_type_trans(skb,dev);
-			}else{
-				++chan->drvstats_rx_intr.rx_intr_bfr_not_passed_to_stack;
-				++chan->ifstats.rx_errors;
-				++card->wandev.stats.rx_errors;
-				goto rx_done;
-			}
-		}else{
-		
-			/* remove hardware header */
-			buf = skb_pull(skb, 1); 
-			
-			if (!wanrouter_type_trans(skb, dev)) {
-				
-				/* can't decapsulate packet */
-				dev_kfree_skb_any(skb);
-
-				++chan->drvstats_rx_intr.rx_intr_bfr_not_passed_to_stack;
-				++chan->ifstats.rx_errors;
-				++card->wandev.stats.rx_errors;
-				goto rx_done;	
-			}
-			skb->mac.raw = skb->data;
-		} 
-		
-
-		/* Send a packet up the IP stack */
-		skb->dev->last_rx = jiffies;
-		netif_rx(skb);
-		++chan->drvstats_rx_intr.rx_intr_bfr_passed_to_stack;
-		++chan->ifstats.rx_packets;
-		++card->wandev.stats.rx_packets;
-
-		chan->ifstats.rx_bytes += len_incl_hdr;
-		card->wandev.stats.rx_bytes += len_incl_hdr;
-	}
-
-rx_done:
-
-       	/* Release buffer element and calculate a pointer to the next one */ 
-       	frbuf->flag = 0;
-	card->rxmb = ++frbuf;
-	if ((void*)frbuf > card->u.f.rxmb_last)
-		card->rxmb = card->u.f.rxmb_base;
-
-}
-
-/*==================================================================
- * tx_intr:	Transmit interrupt handler.
- *
- * Rationale:
- *      If the board is busy transmitting, if_send() will
- *      buffers a single packet and turn on
- *      the tx interrupt. Tx interrupt will be called
- *      by the board, once the firmware can send more
- *      data. Thus, no polling is required.	 
- *
- * Description:
- *	Tx interrupt is called for each 
- *      configured dlci channel. Thus: 
- * 	1. Obtain the netowrk interface based on the
- *         dlci number.
- *      2. Check that network interface is up and
- *         properly setup.
- * 	3. Check for a buffered packet.
- *      4. Transmit the packet.
- *	5. If we are in WANPIPE mode, mark the 
- *         NET_BH handler. 
- *      6. If we are in API mode, kick
- *         the AF_WANPIPE socket for more data. 
- *	   
- */
-static void tx_intr(sdla_t *card)
-{
-        fr508_flags_t* flags = card->flags;
-        fr_tx_buf_ctl_t* bctl;
-        struct net_device* dev;
-        fr_channel_t* chan;
-
-        if(card->hw.type == SDLA_S514){
-                bctl = (void*)(flags->tse_offs + card->hw.dpmbase);
-        }else{
-                bctl = (void*)(flags->tse_offs - FR_MB_VECTOR +
-                        card->hw.dpmbase);
-	}
-
-        /* Find the structure and make it unbusy */
-        dev = find_channel(card, flags->dlci);
-	if (dev == NULL){
-		printk(KERN_INFO "NO DEV IN TX Interrupt\n");	
-		goto end_of_tx_intr;
-	}
-
-        if ((chan = dev->priv) == NULL){
-		printk(KERN_INFO "NO CHAN IN TX Interrupt\n");	
-		goto end_of_tx_intr;
-	}
-
-        if(!chan->transmit_length || !chan->delay_skb) {
-                printk(KERN_INFO "%s: tx int error - transmit length zero\n",
-				card->wandev.name);
-                goto end_of_tx_intr;
-        }
-
-	/* If the 'if_send()' procedure is currently checking the 'tbusy'
-	   status, then we cannot transmit. Instead, we configure the microcode
-	   so as to re-issue this transmit interrupt at a later stage. 
-	*/
-	if (test_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical)) {
-
-		fr_dlci_interface_t* dlci_interface = chan->dlci_int_interface;
-		bctl->flag = 0xA0;
-		dlci_interface->gen_interrupt |= FR_INTR_TXRDY;
-		return;
-
- 	}else{
-        	bctl->dlci = flags->dlci;
-	        bctl->length = chan->transmit_length+chan->fr_header_len;
-        	sdla_poke(&card->hw, 
-		          fr_send_hdr(card,bctl->dlci,bctl->offset), 
-			  chan->delay_skb->data,
- 	              	  chan->delay_skb->len);
-	        bctl->flag = 0xC0;
-
-		++chan->ifstats.tx_packets;
-		++card->wandev.stats.tx_packets;
-		chan->ifstats.tx_bytes += chan->transmit_length;
-		card->wandev.stats.tx_bytes += chan->transmit_length;
-
-		/* We must free an sk buffer, which we used
-		 * for delayed transmission; Otherwise, the sock
-		 * will run out of memory */
-                dev_kfree_skb_any(chan->delay_skb);
-
-		chan->delay_skb = NULL;				
-        	chan->transmit_length = 0;
-
-		dev->trans_start = jiffies;
-
-		if (netif_queue_stopped(dev)){
-			/* If using API, than wakeup socket BH handler */
-			if (chan->common.usedby == API){
-				netif_start_queue(dev);
-				wakeup_sk_bh(dev);
-			}else{
-				netif_wake_queue(dev);
-			}
-		}
-	}
-
-end_of_tx_intr:
-
- 	/* if any other interfaces have transmit interrupts pending, 
-	 * do not disable the global transmit interrupt */
-	if(!(-- card->u.f.tx_interrupts_pending))
-       	        flags->imask &= ~FR_INTR_TXRDY;
-
-
-}
-
-
-/*============================================================================
- * timer_intr:	Timer interrupt handler.
- *
- * Rationale:
- *	All commans must be executed within the timer
- *      interrupt since no two commands should execute
- *      at the same time.
- *
- * Description:
- *	The timer interrupt is used to:
- *    	1. Processing udp calls from 'fpipemon'.
- *    	2. Processing update calls from /proc file system
- *   	3. Reading board-level statistics for 
- *         updating the proc file system.
- *    	4. Sending inverse ARP request packets.
- *	5. Configure a dlci/channel.
- *	6. Unconfigure a dlci/channel. (Node only)
- */
-
-static void timer_intr(sdla_t *card)
-{
-	fr508_flags_t* flags = card->flags;
-
-	/* UDP Debuging: fpipemon call */
-        if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_UDP) {
-		if(card->u.f.udp_type == UDP_FPIPE_TYPE) {
-                    	if(process_udp_mgmt_pkt(card)) {
-		                card->u.f.timer_int_enabled &=
-					~TMR_INT_ENABLED_UDP;
-			}
-		}
-        }
-
-	/* /proc update call : triggered from update() */
-	if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
-		fr_get_err_stats(card);
-		fr_get_stats(card);
-		card->u.f.update_comms_stats = 0;
-		card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE;
-	}
-
-	/* Update the channel state call.  This is call is
-         * triggered by if_send() function */
-	if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_UPDATE_STATE){
-		struct net_device *dev;
-		if (card->wandev.state == WAN_CONNECTED){
-			for (dev = card->wandev.dev; dev;
-			     dev = *((struct net_device **)dev->priv)){
-				fr_channel_t *chan = dev->priv;	
-				if (chan->common.state != WAN_CONNECTED){
-					update_chan_state(dev);
-				}
-			}
-		}
-		card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE_STATE;
-	}
-
-	/* configure a dlci/channel */
-	if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_CONFIG){
-		config_fr(card);
-		card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
-	}
-
-	/* unconfigure a dlci/channel */
-	if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_UNCONFIG){
-		unconfig_fr(card);
-		card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UNCONFIG;
-	}
-
-	
-	/* Transmit ARP packets */
-	if (card->u.f.timer_int_enabled & TMR_INT_ENABLED_ARP){
-		int i=0;
-		struct net_device *dev;
-
-		if (card->u.f.arp_dev == NULL)
-			card->u.f.arp_dev = card->wandev.dev;
-
-		dev = card->u.f.arp_dev;
-
-		for (;;){ 
-
-			fr_channel_t *chan = dev->priv;
-
-			/* If the interface is brought down cancel sending In-ARPs */
-			if (!(dev->flags&IFF_UP)){
-				clear_bit(0,&chan->inarp_ready);	
-			}
-
-			if (test_bit(0,&chan->inarp_ready)){
-
-				if (check_tx_status(card,dev)){
-					set_bit(ARP_CRIT,&card->wandev.critical);
-					break;
-				}
-
-				if (!send_inarp_request(card,dev)){
-					trigger_fr_arp(dev);
-					chan->inarp_tick = jiffies;
-				}
-
-				clear_bit(0,&chan->inarp_ready);
-				dev = move_dev_to_next(card,dev);
-				break;
-			}
-			dev = move_dev_to_next(card,dev);
-
-			if (++i == card->wandev.new_if_cnt){
-				card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_ARP;
-				break;
-			}
-		}
-		card->u.f.arp_dev = dev;
-	}
-
-        if(!card->u.f.timer_int_enabled)
-                flags->imask &= ~FR_INTR_TIMER;
-}
-
-
-/*============================================================================
- * spur_intr:	Spurious interrupt handler.
- * 
- * Description:
- *  	We don't know this interrupt.
- *      Print a warning.
- */
-
-static void spur_intr (sdla_t* card)
-{
-	if (net_ratelimit()){ 
-		printk(KERN_INFO "%s: spurious interrupt!\n", card->devname);
-	}
-}
-
-
-//FIXME: Fix the IPX in next version
-/*===========================================================================
- *  Return 0 for non-IPXWAN packet
- *         1 for IPXWAN packet or IPX is not enabled!
- *  FIXME: Use a IPX structure here not offsets
- */
-static int handle_IPXWAN(unsigned char *sendpacket, 
-			 char *devname, unsigned char enable_IPX, 
-			 unsigned long network_number)
-{
-	int i;
-
-	if( sendpacket[1] == 0x00 && sendpacket[2] == 0x80 &&
-	    sendpacket[6] == 0x81 && sendpacket[7] == 0x37) { 
-
-		/* It's an IPX packet */
-		if (!enable_IPX){
-			/* Return 1 so we don't pass it up the stack. */
-			//FIXME: Take this out when IPX is fixed
-			if (net_ratelimit()){ 
-				printk (KERN_INFO 
-				"%s: WARNING: Unsupported IPX packet received and dropped\n",
-					devname);
-			}
-			return 1;
-		}
-	} else {
-		/* It's not IPX so return and pass it up the stack. */
-		return 0;
-	}
-
-	if( sendpacket[24] == 0x90 && sendpacket[25] == 0x04){
-		/* It's IPXWAN */
-
-		if( sendpacket[10] == 0x02 && sendpacket[42] == 0x00){
-
-			/* It's a timer request packet */
-			printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",
-					devname);
-
-			/* Go through the routing options and answer no to every
-			 * option except Unnumbered RIP/SAP
-			 */
-			for(i = 49; sendpacket[i] == 0x00; i += 5){
-				/* 0x02 is the option for Unnumbered RIP/SAP */
-				if( sendpacket[i + 4] != 0x02){
-					sendpacket[i + 1] = 0;
-				}
-			}
-
-			/* Skip over the extended Node ID option */
-			if( sendpacket[i] == 0x04 ){
-				i += 8;
-			}
-
-			/* We also want to turn off all header compression opt.
-			 */
-			for(; sendpacket[i] == 0x80 ;){
-				sendpacket[i + 1] = 0;
-				i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4;
-			}
-
-			/* Set the packet type to timer response */
-			sendpacket[42] = 0x01;
-
-			printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",
-					devname);
-
-		} else if( sendpacket[42] == 0x02 ){
-
-			/* This is an information request packet */
-			printk(KERN_INFO 
-				"%s: Received IPXWAN Information Request packet\n",
-						devname);
-
-			/* Set the packet type to information response */
-			sendpacket[42] = 0x03;
-
-			/* Set the router name */
-			sendpacket[59] = 'F';
-			sendpacket[60] = 'P';
-			sendpacket[61] = 'I';
-			sendpacket[62] = 'P';
-			sendpacket[63] = 'E';
-			sendpacket[64] = '-';
-			sendpacket[65] = CVHexToAscii(network_number >> 28);
-			sendpacket[66] = CVHexToAscii((network_number & 0x0F000000)>> 24);
-			sendpacket[67] = CVHexToAscii((network_number & 0x00F00000)>> 20);
-			sendpacket[68] = CVHexToAscii((network_number & 0x000F0000)>> 16);
-			sendpacket[69] = CVHexToAscii((network_number & 0x0000F000)>> 12);
-			sendpacket[70] = CVHexToAscii((network_number & 0x00000F00)>> 8);
-			sendpacket[71] = CVHexToAscii((network_number & 0x000000F0)>> 4);
-			sendpacket[72] = CVHexToAscii(network_number & 0x0000000F);
-			for(i = 73; i < 107; i+= 1)
-			{
-				sendpacket[i] = 0;
-			}
-
-			printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",
-					devname);
-		} else {
-
-			printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname);
-			return 0;
-		}
-
-		/* Set the WNodeID to our network address */
-		sendpacket[43] = (unsigned char)(network_number >> 24);
-		sendpacket[44] = (unsigned char)((network_number & 0x00FF0000) >> 16);
-		sendpacket[45] = (unsigned char)((network_number & 0x0000FF00) >> 8);
-		sendpacket[46] = (unsigned char)(network_number & 0x000000FF);
-
-		return 1;
-	}
-
-	/* If we get here, it's an IPX-data packet so it'll get passed up the 
-	 * stack.
-	 * switch the network numbers 
-	 */
-	switch_net_numbers(sendpacket, network_number ,1);
-	return 0;
-}
-/*============================================================================
- * process_route
- * 
- * Rationale:
- *	If the interface goes down, or we receive an ARP request,
- *      we have to change the network interface ip addresses.
- * 	This cannot be done within the interrupt.
- *
- * Description:
- *
- * 	This routine is called as a polling routine to dynamically 
- *	add/delete routes negotiated by inverse ARP.  It is in this 
- *    	"task" because we don't want routes to be added while in 
- *      interrupt context.
- *
- * Usage:
- *	This function is called by fr_poll() polling funtion.
- */
-
-static void process_route(struct net_device *dev)
-{
-	fr_channel_t *chan = dev->priv;
-	sdla_t *card = chan->card;
-
-	struct ifreq if_info;
-	struct sockaddr_in *if_data;
-	mm_segment_t fs = get_fs();
-	u32 ip_tmp;
-	int err;
-
-
-	switch(chan->route_flag){
-
-	case ADD_ROUTE:
-				
-		/* Set remote addresses */
-		memset(&if_info, 0, sizeof(if_info));
-		strcpy(if_info.ifr_name, dev->name);
-
-		set_fs(get_ds());     /* get user space block */ 
-		
-		if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr;
-		if_data->sin_addr.s_addr = chan->ip_remote;
-		if_data->sin_family = AF_INET;
-		err = devinet_ioctl( SIOCSIFDSTADDR, &if_info );
-
-		set_fs(fs);           /* restore old block */
-
-		if (err) {
-			printk(KERN_INFO 
-				"%s: Route Add failed.  Error: %d\n", 
-					card->devname,err);
-			printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
-				chan->name, NIPQUAD(chan->ip_remote));
-
-		}else {
-			printk(KERN_INFO "%s: Route Added Successfully: %u.%u.%u.%u\n",
-				card->devname,NIPQUAD(chan->ip_remote));
-			chan->route_flag = ROUTE_ADDED;
-		}
-		break;
-
-	case REMOVE_ROUTE:
-
-		/* Set remote addresses */
-		memset(&if_info, 0, sizeof(if_info));
-		strcpy(if_info.ifr_name, dev->name);
-
-		ip_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP);	
-
-		set_fs(get_ds());     /* get user space block */ 
-		
-		if_data = (struct sockaddr_in *)&if_info.ifr_dstaddr;
-		if_data->sin_addr.s_addr = 0;
-		if_data->sin_family = AF_INET;
-		err = devinet_ioctl( SIOCSIFDSTADDR, &if_info );
-
-		set_fs(fs);    
-		
-		if (err) {
-			printk(KERN_INFO 
-				"%s: Deleting of route failed.  Error: %d\n", 
-					card->devname,err);
-			printk(KERN_INFO "%s: Address: %u.%u.%u.%u\n",
-				dev->name,NIPQUAD(chan->ip_remote) );
-
-		} else {
-			printk(KERN_INFO "%s: Route Removed Sucessfuly: %u.%u.%u.%u\n", 
-				card->devname,NIPQUAD(ip_tmp));
-			chan->route_flag = NO_ROUTE;
-		}
-		break;
-
-	} /* Case Statement */
-
-}
-
-
-
-/****** Frame Relay Firmware-Specific Functions *****************************/
-
-/*============================================================================
- * Read firmware code version.
- * o fill string str with firmware version info. 
- */
-static int fr_read_version (sdla_t* card, char* str)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		mbox->cmd.command = FR_READ_CODE_VERSION;
-		mbox->cmd.length = 0;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-	
-	if (!err && str) {
-		int len = mbox->cmd.length;
-		memcpy(str, mbox->data, len);
-	        str[len] = '\0';
-	}
-	return err;
-}
-
-/*============================================================================
- * Set global configuration.
- */
-static int fr_configure (sdla_t* card, fr_conf_t *conf)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int dlci_num = card->u.f.dlci_num;
-	int err, i;
-
-	do
-	{
-		memcpy(mbox->data, conf, sizeof(fr_conf_t));
-
-		if (dlci_num) for (i = 0; i < dlci_num; ++i)
-			((fr_conf_t*)mbox->data)->dlci[i] = 
-					card->u.f.node_dlci[i]; 
-		
-		mbox->cmd.command = FR_SET_CONFIG;
-		mbox->cmd.length =
-			sizeof(fr_conf_t) + dlci_num * sizeof(short);
-
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	
-	} while (err && retry-- && fr_event(card, err, mbox));
-
-	/*NC Oct 12 2000 */
-	if (err != CMD_OK){
-		printk(KERN_ERR "%s: Frame Relay Configuration Failed: rc=0x%x\n",
-				card->devname,err);
-	}
-	
-	return err;
-}
-
-/*============================================================================
- * Set DLCI configuration.
- */
-static int fr_dlci_configure (sdla_t* card, fr_dlc_conf_t *conf, unsigned dlci)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memcpy(mbox->data, conf, sizeof(fr_dlc_conf_t));
-		mbox->cmd.dlci = (unsigned short) dlci; 
-		mbox->cmd.command = FR_SET_CONFIG;
-		mbox->cmd.length = sizeof(fr_dlc_conf_t);
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry--);
-	
-	return err;
-}
-/*============================================================================
- * Set interrupt mode.
- */
-static int fr_set_intr_mode (sdla_t* card, unsigned mode, unsigned mtu,
-	unsigned short timeout)
-{
-	fr_mbox_t* mbox = card->mbox;
-	fr508_intr_ctl_t* ictl = (void*)mbox->data;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(ictl, 0, sizeof(fr508_intr_ctl_t));
-		ictl->mode   = mode;
-		ictl->tx_len = mtu;
-		ictl->irq    = card->hw.irq;
-
-		/* indicate timeout on timer */
-		if (mode & 0x20) ictl->timeout = timeout; 
-
-		mbox->cmd.length = sizeof(fr508_intr_ctl_t);
-		mbox->cmd.command = FR_SET_INTR_MODE;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-
-	} while (err && retry-- && fr_event(card, err, mbox));
-	
-	return err;
-}
-
-/*============================================================================
- * Enable communications.
- */
-static int fr_comm_enable (sdla_t* card)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		mbox->cmd.command = FR_COMM_ENABLE;
-		mbox->cmd.length = 0;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-	
-	return err;
-}
-
-/*============================================================================
- * fr_comm_disable 
- *
- * Warning: This functin is called by the shutdown() procedure. It is void
- *          since dev->priv are has already been deallocated and no
- *          error checking is possible using fr_event() function.
- */
-static void fr_comm_disable (sdla_t* card)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do {
-	mbox->cmd.command = FR_SET_MODEM_STATUS;
-	mbox->cmd.length = 1;
-	mbox->data[0] = 0;
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry--);
-	
-	retry = MAX_CMD_RETRY;
-	
-	do
-	{
-		mbox->cmd.command = FR_COMM_DISABLE;
-		mbox->cmd.length = 0;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry--);
-
-	return;
-}
-
-
-
-/*============================================================================
- * Get communications error statistics. 
- */
-static int fr_get_err_stats (sdla_t* card)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-
-	do
-	{
-		mbox->cmd.command = FR_READ_ERROR_STATS;
-		mbox->cmd.length = 0;
-		mbox->cmd.dlci = 0;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-
-	if (!err) {
-		fr_comm_stat_t* stats = (void*)mbox->data;
-		card->wandev.stats.rx_over_errors    = stats->rx_overruns;
-		card->wandev.stats.rx_crc_errors     = stats->rx_bad_crc;
-		card->wandev.stats.rx_missed_errors  = stats->rx_aborts;
-		card->wandev.stats.rx_length_errors  = stats->rx_too_long;
-		card->wandev.stats.tx_aborted_errors = stats->tx_aborts;
-	
-	}
-
-	return err;
-}
-
-/*============================================================================
- * Get statistics. 
- */
-static int fr_get_stats (sdla_t* card)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-
-	do
-	{
-		mbox->cmd.command = FR_READ_STATISTICS;
-		mbox->cmd.length = 0;
-		mbox->cmd.dlci = 0;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-
-	if (!err) {
-		fr_link_stat_t* stats = (void*)mbox->data;
-		card->wandev.stats.rx_frame_errors = stats->rx_bad_format;
-		card->wandev.stats.rx_dropped =
-			stats->rx_dropped + stats->rx_dropped2;
-	}
-
-	return err;
-}
-
-/*============================================================================
- * Add DLCI(s) (Access Node only!).
- * This routine will perform the ADD_DLCIs command for the specified DLCI.
- */
-static int fr_add_dlci (sdla_t* card, int dlci)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		unsigned short* dlci_list = (void*)mbox->data;
-
-		mbox->cmd.length  = sizeof(short);
-		dlci_list[0] = dlci;
-		mbox->cmd.command = FR_ADD_DLCI;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-
-	} while (err && retry-- && fr_event(card, err, mbox));
-	
-	return err;
-}
-
-/*============================================================================
- * Activate DLCI(s) (Access Node only!). 
- * This routine will perform the ACTIVATE_DLCIs command with a DLCI number. 
- */
-static int fr_activate_dlci (sdla_t* card, int dlci)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		unsigned short* dlci_list = (void*)mbox->data;
-
-		mbox->cmd.length  = sizeof(short);
-		dlci_list[0] = dlci;
-		mbox->cmd.command = FR_ACTIVATE_DLCI;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-
-	} while (err && retry-- && fr_event(card, err, mbox));
-	
-	return err;
-}
-
-/*============================================================================
- * Delete DLCI(s) (Access Node only!). 
- * This routine will perform the DELETE_DLCIs command with a DLCI number. 
- */
-static int fr_delete_dlci (sdla_t* card, int dlci)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		unsigned short* dlci_list = (void*)mbox->data;
-
-		mbox->cmd.length  = sizeof(short);
-		dlci_list[0] = dlci;
-		mbox->cmd.command = FR_DELETE_DLCI;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-
-	} while (err && retry-- && fr_event(card, err, mbox));
-	
-	return err;
-}
-
-
-
-/*============================================================================
- * Issue in-channel signalling frame. 
- */
-static int fr_issue_isf (sdla_t* card, int isf)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		mbox->data[0] = isf;
-		mbox->cmd.length  = 1;
-		mbox->cmd.command = FR_ISSUE_IS_FRAME;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-	
-	return err;
-}
-
-
-static unsigned int fr_send_hdr (sdla_t*card, int dlci, unsigned int offset)
-{
-	struct net_device *dev = find_channel(card,dlci);	
-	fr_channel_t *chan;
-
-	if (!dev || !(chan=dev->priv))
-		return offset;
-	
-	if (chan->fr_header_len){
-		sdla_poke(&card->hw, offset, chan->fr_header, chan->fr_header_len);
-	}
-	
-	return offset+chan->fr_header_len;
-}
-
-/*============================================================================
- * Send a frame on a selected DLCI.  
- */
-static int fr_send_data_header (sdla_t* card, int dlci, unsigned char attr, int len,
-	void *buf, unsigned char hdr_len)
-{
-	fr_mbox_t* mbox = card->mbox + 0x800;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		mbox->cmd.dlci    = dlci;
-		mbox->cmd.attr    = attr;
-		mbox->cmd.length  = len+hdr_len;
-		mbox->cmd.command = FR_WRITE;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-
-	if (!err) {
-		fr_tx_buf_ctl_t* frbuf;
- 
-               	if(card->hw.type == SDLA_S514)
-			frbuf = (void*)(*(unsigned long*)mbox->data +
-                        	card->hw.dpmbase);
-		else
-			frbuf = (void*)(*(unsigned long*)mbox->data -
-                        	FR_MB_VECTOR + card->hw.dpmbase);
-
-		sdla_poke(&card->hw, fr_send_hdr(card,dlci,frbuf->offset), buf, len);
-		frbuf->flag = 0x01;
-	}
-
-	return err;
-}
-
-static int fr_send (sdla_t* card, int dlci, unsigned char attr, int len,
-	void *buf)
-{
-	fr_mbox_t* mbox = card->mbox + 0x800;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		mbox->cmd.dlci    = dlci;
-		mbox->cmd.attr    = attr;
-		mbox->cmd.length  = len;
-		mbox->cmd.command = FR_WRITE;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-
-	if (!err) {
-		fr_tx_buf_ctl_t* frbuf;
- 
-               	if(card->hw.type == SDLA_S514)
-			frbuf = (void*)(*(unsigned long*)mbox->data +
-                        	card->hw.dpmbase);
-		else
-			frbuf = (void*)(*(unsigned long*)mbox->data -
-                        	FR_MB_VECTOR + card->hw.dpmbase);
-
-		sdla_poke(&card->hw, frbuf->offset, buf, len);
-		frbuf->flag = 0x01;
-	}
-
-	return err;
-}
-
-
-/****** Firmware Asynchronous Event Handlers ********************************/
-
-/*============================================================================
- * Main asyncronous event/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 fr_event (sdla_t *card, int event, fr_mbox_t* mbox)
-{
-	fr508_flags_t* flags = card->flags;
-	char *ptr = &flags->iflag;
-	int i;
-
-	switch (event) {
-
-		case FRRES_MODEM_FAILURE:
-			return fr_modem_failure(card, mbox);
-
-		case FRRES_CHANNEL_DOWN: {
-			struct net_device *dev;
-
-			/* Remove all routes from associated DLCI's */
-			for (dev = card->wandev.dev; dev;
-			     dev = *((struct net_device **)dev->priv)) {
-				fr_channel_t *chan = dev->priv;
-				if (chan->route_flag == ROUTE_ADDED) {
-					chan->route_flag = REMOVE_ROUTE;
-				}
-
-				if (chan->inarp == INARP_CONFIGURED) {
-					chan->inarp = INARP_REQUEST;
-				}
-
-				/* If the link becomes disconnected then,
-                                 * all channels will be disconnected
-                                 * as well.
-                                 */
-				set_chan_state(dev,WAN_DISCONNECTED);
-			}
-				
-			wanpipe_set_state(card, WAN_DISCONNECTED);
-			return 1;
-			}
-
-		case FRRES_CHANNEL_UP: {
-			struct net_device *dev;
-
-			/* FIXME: Only startup devices that are on the list */
-			
-			for (dev = card->wandev.dev; dev;
-			     dev = *((struct net_device **)dev->priv)) {
-				
-				set_chan_state(dev,WAN_CONNECTED);
-			}
-
-			wanpipe_set_state(card, WAN_CONNECTED);
-			return 1;
-			}
-
-		case FRRES_DLCI_CHANGE:
-			return fr_dlci_change(card, mbox);
-
-		case FRRES_DLCI_MISMATCH:
-			printk(KERN_INFO "%s: DLCI list mismatch!\n", 
-				card->devname);
-			return 1;
-
-		case CMD_TIMEOUT:
-			printk(KERN_ERR "%s: command 0x%02X timed out!\n",
-				card->devname, mbox->cmd.command);
-			printk(KERN_INFO "%s: ID Bytes = ",card->devname);
- 	    		for(i = 0; i < 8; i ++)
-				printk(KERN_INFO "0x%02X ", *(ptr + 0x18 + i));
-	   	 	printk(KERN_INFO "\n");	
-            
-			break;
-
-		case FRRES_DLCI_INACTIVE:
-			break;
- 
-		case FRRES_CIR_OVERFLOW:
-			break;
-			
-		case FRRES_BUFFER_OVERFLOW:
-			break; 
-			
-		default:
-			printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n"
-				, card->devname, mbox->cmd.command, event);
-	}
-
-	return 0;
-}
-
-/*============================================================================
- * Handle modem error.
- *
- * Return zero if previous command has to be cancelled.
- */
-static int fr_modem_failure (sdla_t *card, fr_mbox_t* mbox)
-{
-	printk(KERN_INFO "%s: physical link down! (modem error 0x%02X)\n",
-		card->devname, mbox->data[0]);
-
-	switch (mbox->cmd.command){
-		case FR_WRITE:
-	
-		case FR_READ:
-			return 0;
-	}
-	
-	return 1;
-}
-
-/*============================================================================
- * Handle DLCI status change.
- *
- * Return zero if previous command has to be cancelled.
- */
-static int fr_dlci_change (sdla_t *card, fr_mbox_t* mbox)
-{
-	dlci_status_t* status = (void*)mbox->data;
-	int cnt = mbox->cmd.length / sizeof(dlci_status_t);
-	fr_channel_t *chan;
-	struct net_device* dev2;
-	
-
-	for (; cnt; --cnt, ++status) {
-
-		unsigned short dlci= status->dlci;
-		struct net_device* dev = find_channel(card, dlci);
-		
-		if (dev == NULL){
-			printk(KERN_INFO 
-				"%s: CPE contains unconfigured DLCI= %d\n", 
-				card->devname, dlci); 	
-
-                      printk(KERN_INFO
-                                "%s: unconfigured DLCI %d reported by network\n"
-                                , card->devname, dlci);
- 
-		}else{
-			if (status->state == FR_LINK_INOPER) {
-				printk(KERN_INFO
-					"%s: DLCI %u is inactive!\n",
-					card->devname, dlci);
-
-				if (dev && netif_running(dev))
-					set_chan_state(dev, WAN_DISCONNECTED);
-			}
-	
-			if (status->state & FR_DLCI_DELETED) {
-
-				printk(KERN_INFO
-					"%s: DLCI %u has been deleted!\n",
-					card->devname, dlci);
-
-				if (dev && netif_running(dev)){
-
-					fr_channel_t *chan = dev->priv;
-
-					if (chan->route_flag == ROUTE_ADDED) {
-						chan->route_flag = REMOVE_ROUTE;
-						/* The state change will trigger
-                                                 * the fr polling routine */
-					}
-
-					if (chan->inarp == INARP_CONFIGURED) {
-						chan->inarp = INARP_REQUEST;
-					}
-
-					set_chan_state(dev, WAN_DISCONNECTED);
-				}
-
-			} else if (status->state & FR_DLCI_ACTIVE) {
-
-				chan = dev->priv;
-			
-				/* This flag is used for configuring specific 
-				   DLCI(s) when they become active.
-			 	*/ 
-				chan->dlci_configured = DLCI_CONFIG_PENDING;
-	
-				set_chan_state(dev, WAN_CONNECTED);
-		
-			}
-		}
-	}
-	
-	for (dev2 = card->wandev.dev; dev2;
-	     dev2 = *((struct net_device **)dev2->priv)){
-		
-		chan = dev2->priv;
-	
-		if (chan->dlci_configured == DLCI_CONFIG_PENDING) {
-			if (fr_init_dlci(card, chan)){
-				return 1;
-			}
-		}
-
-	}
-	return 1;
-}
-
-
-static int fr_init_dlci (sdla_t *card, fr_channel_t *chan)
-{
-	fr_dlc_conf_t cfg;
-	
-	memset(&cfg, 0, sizeof(cfg));
-
-	if ( chan->cir_status == CIR_DISABLED) {
-
-		cfg.cir_fwd = cfg.cir_bwd  = 16;
-		cfg.bc_fwd = cfg.bc_bwd = 16;
-		cfg.conf_flags = 0x0001;	
-
-	}else if (chan->cir_status == CIR_ENABLED) {
-	
-		cfg.cir_fwd = cfg.cir_bwd = chan->cir;
-		cfg.bc_fwd  = cfg.bc_bwd  = chan->bc;
-		cfg.be_fwd  = cfg.be_bwd  = chan->be;
-		cfg.conf_flags = 0x0000;
-	}
-	
-	if (fr_dlci_configure( card, &cfg , chan->dlci)){
-		printk(KERN_INFO 
-			"%s: DLCI Configure failed for %d\n",
-				card->devname, chan->dlci);
-		return 1;	
-	}
-	
-	chan->dlci_configured = DLCI_CONFIGURED;
-
-	/* Read the interface byte mapping into the channel 
-	 * structure.
-	 */
-	read_DLCI_IB_mapping( card, chan );
-
-	return 0;
-}
-/******* Miscellaneous ******************************************************/
-
-/*============================================================================
- * Update channel state. 
- */
-static int update_chan_state(struct net_device* dev)
-{
-	fr_channel_t* chan = dev->priv;
-	sdla_t* card = chan->card;
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		mbox->cmd.command = FR_LIST_ACTIVE_DLCI;
-		mbox->cmd.length = 0;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-
-	if (!err) {
-		
-		unsigned short* list = (void*)mbox->data;
-		int cnt = mbox->cmd.length / sizeof(short);
-		
-		err=1;
-		
-		for (; cnt; --cnt, ++list) {
-
-			if (*list == chan->dlci) {
- 				set_chan_state(dev, WAN_CONNECTED);
-
-
-				/* May 23 2000. NC
-				 * When a dlci is added or restarted,
-                                 * the dlci_int_interface pointer must
-				 * be reinitialized.  */
-				if (!chan->dlci_int_interface){
-					err=fr_init_dlci (card,chan);
-				}
-				break;
-			}
-		}
-	}
-
-	return err;
-}
-
-/*============================================================================
- * Set channel state.
- */
-static void set_chan_state(struct net_device* dev, int state)
-{
-	fr_channel_t* chan = dev->priv;
-	sdla_t* card = chan->card;
-
-	if (chan->common.state != state) {
-
-		switch (state) {
-
-			case WAN_CONNECTED:
-				printk(KERN_INFO
-					"%s: Interface %s: DLCI %d connected\n",
-					card->devname, dev->name, chan->dlci);
-
-				/* If the interface was previoulsy down,
-                                 * bring it up, since the channel is active */
-
-				trigger_fr_poll (dev);
-				trigger_fr_arp  (dev);
-				break;
-
-			case WAN_CONNECTING:
-				printk(KERN_INFO 
-				      "%s: Interface %s: DLCI %d connecting\n",
-					card->devname, dev->name, chan->dlci);
-				break;
-
-			case WAN_DISCONNECTED:
-				printk (KERN_INFO 
-				    "%s: Interface %s: DLCI %d disconnected!\n",
-					card->devname, dev->name, chan->dlci);
-			
-				/* If the interface is up, bring it down,
-                                 * since the channel is now disconnected */
-				trigger_fr_poll (dev);
-				break;
-		}
-
-		chan->common.state = state;
-	}
-
-	chan->state_tick = jiffies;
-}
-
-/*============================================================================
- * Find network device by its channel number.
- *
- * We need this critical flag because we change
- * the dlci_to_dev_map outside the interrupt.
- *
- * NOTE: del_if() functions updates this array, it uses
- *       the spin locks to avoid corruption.
- */
-static struct net_device* find_channel(sdla_t* card, unsigned dlci)
-{
-	if(dlci > HIGHEST_VALID_DLCI)
-		return NULL;
-
-	return(card->u.f.dlci_to_dev_map[dlci]);
-}
-
-/*============================================================================
- * Check to see if a frame can be sent. If no transmit buffers available,
- * enable transmit interrupts.
- *
- * Return:	1 - Tx buffer(s) available
- *		0 - no buffers available
- */
-static int is_tx_ready (sdla_t* card, fr_channel_t* chan)
-{
-	unsigned char sb;
-
-        if(card->hw.type == SDLA_S514)
-		return 1;
-
-	sb = inb(card->hw.port);
-	if (sb & 0x02) 
-		return 1;
-
-	return 0;
-}
-
-/*============================================================================
- * Convert decimal string to unsigned integer.
- * If len != 0 then only 'len' characters of the string are converted.
- */
-static unsigned int dec_to_uint (unsigned char* str, int len)
-{
-	unsigned val;
-
-	if (!len) 
-		len = strlen(str);
-
-	for (val = 0; len && isdigit(*str); ++str, --len)
-		val = (val * 10) + (*str - (unsigned)'0');
-
-	return val;
-}
-
-
-
-/*=============================================================================
- * Store a UDP management packet for later processing.
- */
-
-static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card,
-                                struct sk_buff *skb, int dlci)
-{
-        int udp_pkt_stored = 0;
-	
-	struct net_device *dev = find_channel(card, dlci);
-	fr_channel_t *chan;
-	
-	if (!dev || !(chan=dev->priv))
-		return 1;
-	
-        if(!card->u.f.udp_pkt_lgth && (skb->len <= MAX_LGTH_UDP_MGNT_PKT)){
-                card->u.f.udp_pkt_lgth = skb->len + chan->fr_header_len;
-                card->u.f.udp_type = udp_type;
-                card->u.f.udp_pkt_src = udp_pkt_src;
-                card->u.f.udp_dlci = dlci;
-                memcpy(card->u.f.udp_pkt_data, skb->data, skb->len);
-                card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UDP;
-                udp_pkt_stored = 1;
-
-        }else{
-                printk(KERN_INFO "ERROR: UDP packet not stored for DLCI %d\n", 
-							dlci);
-	}
-
-        if(udp_pkt_src == UDP_PKT_FRM_STACK){
-                dev_kfree_skb_any(skb);
-	}else{
-                dev_kfree_skb_any(skb);
-	}
-		
-        return(udp_pkt_stored);
-}
-
-
-/*==============================================================================
- * Process UDP call of type FPIPE8ND
- */
-static int process_udp_mgmt_pkt(sdla_t* card)
-{
-
-	int c_retry = MAX_CMD_RETRY;
-	unsigned char *buf;
-	unsigned char frames;
-	unsigned int len;
-	unsigned short buffer_length;
-	struct sk_buff *new_skb;
-	fr_mbox_t* mbox = card->mbox;
-	int err;
-	struct timeval tv;
-	int udp_mgmt_req_valid = 1;
-        struct net_device* dev;
-        fr_channel_t* chan;
-        fr_udp_pkt_t *fr_udp_pkt;
-	unsigned short num_trc_els;
-	fr_trc_el_t* ptr_trc_el;
-	fr_trc_el_t trc_el;
-	fpipemon_trc_t* fpipemon_trc;
-
-	char udp_pkt_src = card->u.f.udp_pkt_src; 
-	int dlci = card->u.f.udp_dlci;
-
-	/* Find network interface for this packet */
-	dev = find_channel(card, dlci);
-	if (!dev){
-		card->u.f.udp_pkt_lgth = 0;
-		return 1;
-	}
-        if ((chan = dev->priv) == NULL){
-		card->u.f.udp_pkt_lgth = 0;
-		return 1;
-	}
-
-	/* If the UDP packet is from the network, we are going to have to 
-	   transmit a response. Before doing so, we must check to see that
-	   we are not currently transmitting a frame (in 'if_send()') and
-	   that we are not already in a 'delayed transmit' state.
-	*/
-	if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-		if (check_tx_status(card,dev)){
-			card->u.f.udp_pkt_lgth = 0;
-			return 1;
-		}
-        }
-
-        fr_udp_pkt = (fr_udp_pkt_t *)card->u.f.udp_pkt_data;
-
-	if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-	
-		switch(fr_udp_pkt->cblock.command) {
-
-			case FR_READ_MODEM_STATUS:
-			case FR_READ_STATUS:
-			case FPIPE_ROUTER_UP_TIME:
-			case FR_READ_ERROR_STATS:
-			case FPIPE_DRIVER_STAT_GEN:
-			case FR_READ_STATISTICS:
-			case FR_READ_ADD_DLC_STATS:
-			case FR_READ_CONFIG:
-			case FR_READ_CODE_VERSION:
-				udp_mgmt_req_valid = 1;
-				break;
-			default:
-				udp_mgmt_req_valid = 0;
-				break;
-		}
-	}
-
-	if(!udp_mgmt_req_valid) {
-		/* set length to 0 */
-		fr_udp_pkt->cblock.length = 0;
-		/* set return code */
-		fr_udp_pkt->cblock.result = 0xCD; 
-		
-		chan->drvstats_gen.UDP_PIPE_mgmt_direction_err ++;
-
-		if (net_ratelimit()){	
-			printk(KERN_INFO 
-			"%s: Warning, Illegal UDP command attempted from network: %x\n",
-			card->devname,fr_udp_pkt->cblock.command);
-		}
-		
-	} else {   
-           
-		switch(fr_udp_pkt->cblock.command) {
-
-		case FPIPE_ENABLE_TRACING:
-			if(!card->TracingEnabled) {
-				do {
-                       			mbox->cmd.command = FR_SET_TRACE_CONFIG;
-                       			mbox->cmd.length = 1;
-                     			mbox->cmd.dlci = 0x00;
-                   			mbox->data[0] = fr_udp_pkt->data[0] | 
-						RESET_TRC;
-                    			err = sdla_exec(mbox) ? 
-					     		mbox->cmd.result : CMD_TIMEOUT;
-                       		} while (err && c_retry-- && fr_event(card, err,
-					 mbox));
-
-                        	if(err) {
-					card->TracingEnabled = 0;
-					/* set the return code */
-					fr_udp_pkt->cblock.result =
-  						mbox->cmd.result;
-					mbox->cmd.length = 0;
-					break;
-				}
-
-				sdla_peek(&card->hw, NO_TRC_ELEMENTS_OFF,
-						&num_trc_els, 2);
-				sdla_peek(&card->hw, BASE_TRC_ELEMENTS_OFF,
-						&card->u.f.trc_el_base, 4);
-				card->u.f.curr_trc_el = card->u.f.trc_el_base;
-             			card->u.f.trc_el_last = card->u.f.curr_trc_el +
-							((num_trc_els - 1) * 
-							sizeof(fr_trc_el_t));
-   
-				/* Calculate the maximum trace data area in */
-				/* the UDP packet */
-				card->u.f.trc_bfr_space=(MAX_LGTH_UDP_MGNT_PKT -
-					//sizeof(fr_encap_hdr_t) -
-					sizeof(ip_pkt_t) -
-					sizeof(udp_pkt_t) -
-					sizeof(wp_mgmt_t) -
-					sizeof(cblock_t));
-
-				/* set return code */
-				fr_udp_pkt->cblock.result = 0;
-			
-			} else {
-                        	/* set return code to line trace already 
-				   enabled */
-				fr_udp_pkt->cblock.result = 1;
-                    	}
-
-			mbox->cmd.length = 0;
-			card->TracingEnabled = 1;
-			break;
-
-
-                case FPIPE_DISABLE_TRACING:
-			if(card->TracingEnabled) {
-			
-				do {
-					mbox->cmd.command = FR_SET_TRACE_CONFIG;
-					mbox->cmd.length = 1;
-					mbox->cmd.dlci = 0x00;
-					mbox->data[0] = ~ACTIVATE_TRC;
-					err = sdla_exec(mbox) ? 
-							mbox->cmd.result : CMD_TIMEOUT;
-				} while (err && c_retry-- && fr_event(card, err, mbox));
-                    	}
-
-                    	/* set return code */
-			fr_udp_pkt->cblock.result = 0;
-			mbox->cmd.length = 0;
-			card->TracingEnabled = 0;
-			break;
-
-                case FPIPE_GET_TRACE_INFO:
-
-		        /* Line trace cannot be performed on the 502 */
-                        if(!card->TracingEnabled) {
-                                /* set return code */
-                                fr_udp_pkt->cblock.result = 1;
-                                mbox->cmd.length = 0;
-                                break;
-                        }
-
-			ptr_trc_el = (void *)card->u.f.curr_trc_el;
-
-                        buffer_length = 0;
-			fr_udp_pkt->data[0x00] = 0x00;
-
-                        for(frames = 0; frames < MAX_FRMS_TRACED; frames ++) {
-
-                                sdla_peek(&card->hw, (unsigned long)ptr_trc_el,
-					  (void *)&trc_el.flag,
-					  sizeof(fr_trc_el_t));
-                                if(trc_el.flag == 0x00) {
-                                        break;
-				}
-                                if((card->u.f.trc_bfr_space - buffer_length)
-                                        < sizeof(fpipemon_trc_hdr_t)) { 
-                                        fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
-                                        break;
-                                }
-
-				fpipemon_trc = 
-					(fpipemon_trc_t *)&fr_udp_pkt->data[buffer_length]; 
-				fpipemon_trc->fpipemon_trc_hdr.status =
-					trc_el.attr;
-                            	fpipemon_trc->fpipemon_trc_hdr.tmstamp =
-					trc_el.tmstamp;
-                            	fpipemon_trc->fpipemon_trc_hdr.length = 
-					trc_el.length;
-
-                                if(!trc_el.offset || !trc_el.length) {
-
-                                     	fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00;
-
- 				}else if((trc_el.length + sizeof(fpipemon_trc_hdr_t) + 1) >
-					(card->u.f.trc_bfr_space - buffer_length)){
-
-                                        fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x00;
-                                    	fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
- 
-                                }else {
-                                        fpipemon_trc->fpipemon_trc_hdr.data_passed = 0x01;
-                                        sdla_peek(&card->hw, trc_el.offset,
-                           			  fpipemon_trc->data,
-						  trc_el.length);
-				}			
-
-                                trc_el.flag = 0x00;
-                                sdla_poke(&card->hw, (unsigned long)ptr_trc_el,
-					  &trc_el.flag, 1);
-                               
-				ptr_trc_el ++;
-				if((void *)ptr_trc_el > card->u.f.trc_el_last)
-					ptr_trc_el = (void*)card->u.f.trc_el_base;
-
-				buffer_length += sizeof(fpipemon_trc_hdr_t);
-                               	if(fpipemon_trc->fpipemon_trc_hdr.data_passed) {
-                               		buffer_length += trc_el.length;
-                               	}
-
-				if(fr_udp_pkt->data[0x00] & MORE_TRC_DATA) {
-					break;
-				}
-                        }
-                      
-			if(frames == MAX_FRMS_TRACED) {
-                        	fr_udp_pkt->data[0x00] |= MORE_TRC_DATA;
-			}
-             
-			card->u.f.curr_trc_el = (void *)ptr_trc_el;
-
-                        /* set the total number of frames passed */
-			fr_udp_pkt->data[0x00] |=
-				((frames << 1) & (MAX_FRMS_TRACED << 1));
-
-                        /* set the data length and return code */
-			fr_udp_pkt->cblock.length = mbox->cmd.length = buffer_length;
-                        fr_udp_pkt->cblock.result = 0;
-                        break;
-
-                case FPIPE_FT1_READ_STATUS:
-			sdla_peek(&card->hw, 0xF020,
-				&fr_udp_pkt->data[0x00] , 2);
-			fr_udp_pkt->cblock.length = mbox->cmd.length = 2;
-			fr_udp_pkt->cblock.result = 0;
-			break;
-
-		case FPIPE_FLUSH_DRIVER_STATS:
-			init_chan_statistics(chan);
-			init_global_statistics(card);
-			mbox->cmd.length = 0;
-			break;
-		
-		case FPIPE_ROUTER_UP_TIME:
-			do_gettimeofday(&tv);
-			chan->router_up_time = tv.tv_sec - 
-						chan->router_start_time;
-    	                *(unsigned long *)&fr_udp_pkt->data =
-    				chan->router_up_time;	
-			mbox->cmd.length = fr_udp_pkt->cblock.length = 4;
-			fr_udp_pkt->cblock.result = 0;
-			break;
-
-		case FPIPE_DRIVER_STAT_IFSEND:
-			memcpy(fr_udp_pkt->data,
-				&chan->drvstats_if_send.if_send_entry,
-				sizeof(if_send_stat_t));
-			mbox->cmd.length = fr_udp_pkt->cblock.length =sizeof(if_send_stat_t);	
-			fr_udp_pkt->cblock.result = 0;
-			break;
-	
-		case FPIPE_DRIVER_STAT_INTR:
-
-			memcpy(fr_udp_pkt->data,
-                                &card->statistics.isr_entry,
-                                sizeof(global_stats_t));
-
-                        memcpy(&fr_udp_pkt->data[sizeof(global_stats_t)],
-                                &chan->drvstats_rx_intr.rx_intr_no_socket,
-                                sizeof(rx_intr_stat_t));
-
-			mbox->cmd.length = fr_udp_pkt->cblock.length = 
-					sizeof(global_stats_t) +
-					sizeof(rx_intr_stat_t);
-			fr_udp_pkt->cblock.result = 0;
-			break;
-
-		case FPIPE_DRIVER_STAT_GEN:
-                        memcpy(fr_udp_pkt->data,
-                                &chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err,
-                                sizeof(pipe_mgmt_stat_t));
-
-                        memcpy(&fr_udp_pkt->data[sizeof(pipe_mgmt_stat_t)],
-                               &card->statistics, sizeof(global_stats_t));
-
-                        mbox->cmd.length = fr_udp_pkt->cblock.length = sizeof(global_stats_t)+
-                                                     sizeof(rx_intr_stat_t);
-			fr_udp_pkt->cblock.result = 0;
-                        break;
-
-
-		case FR_FT1_STATUS_CTRL:
-			if(fr_udp_pkt->data[0] == 1) {
-				if(rCount++ != 0 ){
-					fr_udp_pkt->cblock.result = 0;
-					mbox->cmd.length = 1;
-					break;
-				} 
-			}
-           
-			/* Disable FT1 MONITOR STATUS */
-                        if(fr_udp_pkt->data[0] == 0) {
-				if( --rCount != 0) {
-                                        fr_udp_pkt->cblock.result = 0;
-					mbox->cmd.length = 1;
-					break;
-				} 
-			}  
-			goto udp_mgmt_dflt;
-
-			
-		default:
-udp_mgmt_dflt:
- 			do {
-				memcpy(&mbox->cmd,
-					&fr_udp_pkt->cblock.command,
-					sizeof(fr_cmd_t));
-				if(mbox->cmd.length) {
-					memcpy(&mbox->data,
-						(char *)fr_udp_pkt->data,
-						mbox->cmd.length);
-				}
- 				
-				err = sdla_exec(mbox) ? mbox->cmd.result : 
-					CMD_TIMEOUT;
-			} while (err && c_retry-- && fr_event(card, err, mbox));
-
-			if(!err)
-				chan->drvstats_gen.
-					UDP_PIPE_mgmt_adptr_cmnd_OK ++;
-			else
-                                chan->drvstats_gen.
-					UDP_PIPE_mgmt_adptr_cmnd_timeout ++;
-
-       	                /* copy the result back to our buffer */
-			memcpy(&fr_udp_pkt->cblock.command,
-				&mbox->cmd, sizeof(fr_cmd_t));
-
-                       	if(mbox->cmd.length) {
-                               	memcpy(&fr_udp_pkt->data,
-					&mbox->data, mbox->cmd.length);
-			}
-		} 
-        }
-   
-        /* Fill UDP TTL */
-        fr_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
-        len = reply_udp(card->u.f.udp_pkt_data, mbox->cmd.length);
-
-        if(udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-
-		chan->fr_header_len=2;
-		chan->fr_header[0]=Q922_UI;
-		chan->fr_header[1]=NLPID_IP;
-			
-		err = fr_send_data_header(card, dlci, 0, len, 
-			card->u.f.udp_pkt_data,chan->fr_header_len);
-		if (err){ 
-			chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_passed ++;
-		}else{
-			chan->drvstats_gen.UDP_PIPE_mgmt_adptr_send_failed ++;
-		}
-		
-	} else {
-		/* Allocate socket buffer */
-		if((new_skb = dev_alloc_skb(len)) != NULL) {
-
-			/* copy data into new_skb */
-			buf = skb_put(new_skb, len);
-			memcpy(buf, card->u.f.udp_pkt_data, len);
-        
-			chan->drvstats_gen.
-				UDP_PIPE_mgmt_passed_to_stack ++;
-			new_skb->dev = dev;
-			new_skb->protocol = htons(ETH_P_IP);
-			new_skb->mac.raw = new_skb->data;
-			netif_rx(new_skb);
-            	
-		} else {
-			chan->drvstats_gen.UDP_PIPE_mgmt_no_socket ++;
-			printk(KERN_INFO 
-			"%s: UDP mgmt cmnd, no socket buffers available!\n", 
-			card->devname);
-            	}
-        }
-
-	card->u.f.udp_pkt_lgth = 0;
-
-	return 1;
-}
-
-/*==============================================================================
- * Send Inverse ARP Request
- */
-
-int send_inarp_request(sdla_t *card, struct net_device *dev)
-{
-	int err=0;
-
-	arphdr_1490_t *ArpPacket;
-	arphdr_fr_t *arphdr;
-	fr_channel_t *chan = dev->priv;
-	struct in_device *in_dev;
-
-	in_dev = dev->ip_ptr;
-
-	if(in_dev != NULL ) {	
-
-		ArpPacket = kmalloc(sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t), GFP_ATOMIC);
-		/* SNAP Header indicating ARP */
-		ArpPacket->control	= 0x03;
-		ArpPacket->pad		= 0x00;
-		ArpPacket->NLPID	= 0x80;
-		ArpPacket->OUI[0]	= 0;
-		ArpPacket->OUI[1]	= 0;
-		ArpPacket->OUI[2]	= 0;
-		ArpPacket->PID		= 0x0608;
-
-		arphdr = (arphdr_fr_t *)(ArpPacket + 1); // Go to ARP Packet
-
-		/* InARP request */		
-		arphdr->ar_hrd = 0x0F00;	/* Frame Relay HW type */
-		arphdr->ar_pro = 0x0008;	/* IP Protocol	       */
-		arphdr->ar_hln = 2;		/* HW addr length      */
-		arphdr->ar_pln = 4;		/* IP addr length      */
-		arphdr->ar_op = htons(0x08);	/* InARP Request       */
-		arphdr->ar_sha = 0; 		/* src HW DLCI - Doesn't matter */
-		if(in_dev->ifa_list != NULL)
-			arphdr->ar_sip = in_dev->ifa_list->ifa_local;  /* Local Address       */else
-			arphdr->ar_sip = 0;
-		arphdr->ar_tha = 0; 		/* dst HW DLCI - Doesn't matter */
-		arphdr->ar_tip = 0;		/* Remote Address -- what we want */
-
-		err = fr_send(card, chan->dlci, 0, sizeof(arphdr_1490_t) + sizeof(arphdr_fr_t),
-		   			(void *)ArpPacket);
-
-		if (!err){
-			printk(KERN_INFO "\n%s: Sending InARP request on DLCI %d.\n", 
-				card->devname, chan->dlci);
-			clear_bit(ARP_CRIT,&card->wandev.critical);
-		}
-
-		kfree(ArpPacket);
-	}else{
-		printk(KERN_INFO "%s: INARP ERROR: %s doesn't have a local IP address!\n",
-				card->devname,dev->name);
-		return 1;
-	}
-
-	return 0;
-}
-	
-
-/*==============================================================================
- * Check packet for ARP Type
- */
-
-int is_arp(void *buf)
-{
-	arphdr_1490_t *arphdr = (arphdr_1490_t *)buf;
-	
-	if (arphdr->pad   == 0x00  &&
-	    arphdr->NLPID == 0x80  &&
-	    arphdr->PID   == 0x0608) 
-		return 1;
-	else return 0;
-}
-
-/*==============================================================================
- * Process ARP Packet Type
- */
-
-int process_ARP(arphdr_1490_t *ArpPacket, sdla_t *card, struct net_device* dev)
-{
-
-
-	arphdr_fr_t *arphdr = (arphdr_fr_t *)(ArpPacket + 1); /* Skip header */
-	fr_rx_buf_ctl_t* frbuf = card->rxmb;
-	struct in_device *in_dev;
-	fr_channel_t *chan = dev->priv;		
-	
-	/* Before we transmit ARP packet, we must check 
-	 * to see that we are not currently transmitting a 
-	 * frame (in 'if_send()') and that we are not 
-	 * already in a 'delayed transmit' state. */
-	if (check_tx_status(card,dev)){
-		if (net_ratelimit()){ 	
-			printk(KERN_INFO "%s: Disabling comminication to process ARP\n",
-					card->devname);
-		}
-		set_bit(ARP_CRIT,&card->wandev.critical);
-		return 0;
-	}
-
-	in_dev = dev->ip_ptr;
-
-	/* Check that IP addresses exist for our network address */
-	if (in_dev == NULL || in_dev->ifa_list == NULL) 
-		return -1;
-
-	switch (ntohs(arphdr->ar_op)) {
-
-	case 0x08:  // Inverse ARP request  -- Send Reply, add route.
-			
-		/* Check for valid Address */
-		printk(KERN_INFO "%s: Recvd PtP addr -InArp Req: %u.%u.%u.%u\n", 
-			card->devname, NIPQUAD(arphdr->ar_sip));
-
-
-		/* Check that the network address is the same as ours, only
-                 * if the netowrk mask is not 255.255.255.255. Otherwise
-                 * this check would not make sense */
-
-		if (in_dev->ifa_list->ifa_mask != 0xFFFFFFFF && 
-		    (in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != 
-		    (in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)){
-			printk(KERN_INFO 
-				"%s: Invalid PtP address. %u.%u.%u.%u  InARP ignored.\n", 
-					card->devname,NIPQUAD(arphdr->ar_sip));
-
-			printk(KERN_INFO "%s: mask %u.%u.%u.%u\n", 
-				card->devname, NIPQUAD(in_dev->ifa_list->ifa_mask));
-				printk(KERN_INFO "%s: local %u.%u.%u.%u\n", 
-				card->devname,NIPQUAD(in_dev->ifa_list->ifa_local));
-			return -1;
-		}
-
-		if (in_dev->ifa_list->ifa_local == arphdr->ar_sip){
-			printk(KERN_INFO 
-				"%s: Local addr = PtP addr.  InARP ignored.\n", 
-					card->devname);
-			return -1;
-		}
-	
-		arphdr->ar_op = htons(0x09);	/* InARP Reply */
-
-		/* Set addresses */
-		arphdr->ar_tip = arphdr->ar_sip;
-		arphdr->ar_sip = in_dev->ifa_list->ifa_local;
-
-		chan->ip_local = in_dev->ifa_list->ifa_local;
-		chan->ip_remote = arphdr->ar_sip;
-
-		fr_send(card, frbuf->dlci, 0, frbuf->length, (void *)ArpPacket);
-
-		if (test_bit(ARP_CRIT,&card->wandev.critical)){
-			if (net_ratelimit()){ 	
-				printk(KERN_INFO "%s: ARP Processed Enabling Communication!\n",
-					card->devname);
-			}
-		}
-		clear_bit(ARP_CRIT,&card->wandev.critical);
-		
-		chan->ip_local = in_dev->ifa_list->ifa_local;
-		chan->ip_remote = arphdr->ar_sip;
-
-		/* Add Route Flag */
-		/* The route will be added in the polling routine so
-		   that it is not interrupt context. */
-
-		chan->route_flag = ADD_ROUTE;
-		trigger_fr_poll (dev);
-
-		break;
-
-	case 0x09:  // Inverse ARP reply
-
-		/* Check for valid Address */
-		printk(KERN_INFO "%s: Recvd PtP addr %u.%u.%u.%u -InArp Reply\n", 
-				card->devname, NIPQUAD(arphdr->ar_sip));
-
-
-		/* Compare network addresses, only if network mask
-                 * is not 255.255.255.255  It would not make sense
-                 * to perform this test if the mask was all 1's */
-
-		if (in_dev->ifa_list->ifa_mask != 0xffffffff &&
-		    (in_dev->ifa_list->ifa_mask & arphdr->ar_sip) != 
-			(in_dev->ifa_list->ifa_mask & in_dev->ifa_list->ifa_local)) {
-
-			printk(KERN_INFO "%s: Invalid PtP address.  InARP ignored.\n", 
-					card->devname);
-			return -1;
-		}
-
-		/* Make sure that the received IP address is not
-                 * the same as our own local address */
-		if (in_dev->ifa_list->ifa_local == arphdr->ar_sip) {
-			printk(KERN_INFO "%s: Local addr = PtP addr.  InARP ignored.\n", 
-				card->devname);
-			return -1;
-		}			
-
-		chan->ip_local  = in_dev->ifa_list->ifa_local;
-		chan->ip_remote = arphdr->ar_sip;
-
-		/* Add Route Flag */
-		/* The route will be added in the polling routine so
-		   that it is not interrupt context. */
-
-		chan->route_flag = ADD_ROUTE;
-		chan->inarp = INARP_CONFIGURED;
-		trigger_fr_poll(dev);
-		
-		break;
-	default:
-		break; // ARP's and RARP's -- Shouldn't happen.
-	}
-
-	return 0;	
-}
-
-
-/*============================================================
- * trigger_fr_arp
- *
- * Description:
- * 	Add an fr_arp() task into a arp
- *      timer handler for a specific dlci/interface.  
- *      This will kick the fr_arp() routine 
- *      within the specified time interval. 
- *
- * Usage:
- * 	This timer is used to send ARP requests at
- *      certain time intervals. 
- * 	Called by an interrupt to request an action
- *      at a later date.
- */	
-
-static void trigger_fr_arp(struct net_device *dev)
-{
-	fr_channel_t* chan = dev->priv;
-
-	mod_timer(&chan->fr_arp_timer, jiffies + chan->inarp_interval * HZ);
-	return;
-}
-
-
-
-/*==============================================================================
- * ARP Request Action
- *
- *	This funciton is called by timer interrupt to send an arp request
- *      to the remote end.
- */
-
-static void fr_arp (unsigned long data)
-{
-	struct net_device *dev = (struct net_device *)data;
-	fr_channel_t *chan = dev->priv;
-	volatile sdla_t *card = chan->card;
-	fr508_flags_t* flags = card->flags;
-
-	/* Send ARP packets for all devs' until
-         * ARP state changes to CONFIGURED */
-
-	if (chan->inarp == INARP_REQUEST &&
-	    chan->common.state == WAN_CONNECTED && 
-	    card->wandev.state == WAN_CONNECTED){
-		set_bit(0,&chan->inarp_ready);
-		card->u.f.timer_int_enabled |= TMR_INT_ENABLED_ARP;
-		flags->imask |= FR_INTR_TIMER;	
-	}
- 
-	return;
-}
-	
-
-/*==============================================================================
- * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR_
- * TEST_COUNTER times.
- */
-static int intr_test( sdla_t* card )
-{
-	fr_mbox_t* mb = card->mbox;
-	int err,i;
-
-        err = fr_set_intr_mode(card, FR_INTR_READY, card->wandev.mtu, 0 );
-	
-	if (err == CMD_OK) {
-
-		for ( i = 0; i < MAX_INTR_TEST_COUNTER; i++ ) {
- 			/* Run command READ_CODE_VERSION */
-			mb->cmd.length  = 0;
-			mb->cmd.command = FR_READ_CODE_VERSION;
-			err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-			if (err != CMD_OK) 
-				fr_event(card, err, mb);
-		}
-	
-	} else {
-		return err;	
-	}
-
-	err = fr_set_intr_mode( card, 0, card->wandev.mtu, 0 );
-
-	if( err != CMD_OK ) 
-		return err;
-
-	return 0;
-}
-
-/*==============================================================================
- * Determine what type of UDP call it is. FPIPE8ND ?
- */
-static int udp_pkt_type( struct sk_buff *skb, sdla_t* card )
-{
-	fr_udp_pkt_t *fr_udp_pkt = (fr_udp_pkt_t *)skb->data;
-
-	/* Quick HACK */
-	
-	
-        if((fr_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
-		(fr_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45) &&
-		(fr_udp_pkt->udp_pkt.udp_dst_port == 
-		ntohs(card->wandev.udp_port)) &&
-		(fr_udp_pkt->wp_mgmt.request_reply == 
-		UDPMGMT_REQUEST)) {
-                        if(!strncmp(fr_udp_pkt->wp_mgmt.signature,
-                                UDPMGMT_FPIPE_SIGNATURE, 8)){
-                                return UDP_FPIPE_TYPE;
-			}
-	}
-        return UDP_INVALID_TYPE;
-}
-
-
-/*==============================================================================
- * Initializes the Statistics values in the fr_channel structure.
- */
-void init_chan_statistics( fr_channel_t* chan)
-{
-        memset(&chan->drvstats_if_send.if_send_entry, 0,
-		sizeof(if_send_stat_t));
-        memset(&chan->drvstats_rx_intr.rx_intr_no_socket, 0,
-                sizeof(rx_intr_stat_t));
-        memset(&chan->drvstats_gen.UDP_PIPE_mgmt_kmalloc_err, 0,
-                sizeof(pipe_mgmt_stat_t));
-}
-	
-/*==============================================================================
- * Initializes the Statistics values in the Sdla_t structure.
- */
-void init_global_statistics( sdla_t* card )
-{
-	/* Intialize global statistics for a card */
-        memset(&card->statistics.isr_entry, 0, sizeof(global_stats_t));
-}
-
-static void read_DLCI_IB_mapping( sdla_t* card, fr_channel_t* chan )
-{
-	fr_mbox_t* mbox = card->mbox;
-	int retry = MAX_CMD_RETRY;	
-	dlci_IB_mapping_t* result; 
-	int err, counter, found;	
-
-	do {
-		mbox->cmd.command = FR_READ_DLCI_IB_MAPPING;
-		mbox->cmd.length = 0;	
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && fr_event(card, err, mbox));
-
-	if( mbox->cmd.result != 0){
-		printk(KERN_INFO "%s: Read DLCI IB Mapping failed\n", 
-			chan->name);
-	}
-
-	counter = mbox->cmd.length / sizeof(dlci_IB_mapping_t);
-	result = (void *)mbox->data;
-	
-	found = 0;
-	for (; counter; --counter, ++result) {
-		if ( result->dlci == chan->dlci ) {
-			chan->IB_addr = result->addr_value;
-			if(card->hw.type == SDLA_S514){
-	             		chan->dlci_int_interface =
-					(void*)(card->hw.dpmbase +
-					chan->IB_addr);
-       			}else{ 
-				chan->dlci_int_interface = 
-					(void*)(card->hw.dpmbase + 
-					(chan->IB_addr & 0x00001FFF));
-
-			}
-			found = 1;
-			break;	
-		} 
-	}
-	if (!found)
-		printk( KERN_INFO "%s: DLCI %d not found by IB MAPPING cmd\n", 
-		card->devname, chan->dlci);
-}
-
-
-
-void s508_s514_lock(sdla_t *card, unsigned long *smp_flags)
-{
-	if (card->hw.type != SDLA_S514){
-
-		spin_lock_irqsave(&card->wandev.lock, *smp_flags);
-	}else{
-		spin_lock(&card->u.f.if_send_lock);
-	}
-	return;
-}
-
-
-void s508_s514_unlock(sdla_t *card, unsigned long *smp_flags)
-{
-	if (card->hw.type != SDLA_S514){
-
-		spin_unlock_irqrestore (&card->wandev.lock, *smp_flags);
-	}else{
-		spin_unlock(&card->u.f.if_send_lock);
-	}
-	return;
-}
-
-
-
-/*----------------------------------------------------------------------
-                  RECEIVE INTERRUPT: BOTTOM HALF HANDLERS 
- ----------------------------------------------------------------------*/
-
-
-/*========================================================
- * bh_enqueue
- *
- * Description:
- *	Insert a received packet into a circular
- *      rx queue.  This packet will be picked up 
- *      by fr_bh() and sent up the stack to the
- *      user.
- *       	
- * Usage: 
- *	This function is called by rx interrupt,
- *      in API mode.
- *
- */
-
-static int bh_enqueue(struct net_device *dev, struct sk_buff *skb)
-{
-	/* Check for full */
-	fr_channel_t* chan = dev->priv;
-	sdla_t *card = chan->card;
-
-
-	if (atomic_read(&chan->bh_buff_used) == MAX_BH_BUFF){
-		++card->wandev.stats.rx_dropped;
-		dev_kfree_skb_any(skb);
-		return 1; 
-	}
-
-	((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb;
-
-	if (chan->bh_write == (MAX_BH_BUFF-1)){
-		chan->bh_write=0;
-	}else{
-		++chan->bh_write;
-	}
-
-	atomic_inc(&chan->bh_buff_used);
-
-	return 0;
-}
-
-
-/*========================================================
- * trigger_fr_bh
- *
- * Description:
- * 	Kick the fr_bh() handler
- *
- * Usage:
- *	rx interrupt calls this function during
- *      the API mode. 
- */
-
-static void trigger_fr_bh (fr_channel_t *chan)
-{
-	if (!test_and_set_bit(0,&chan->tq_working)){
-		wanpipe_queue_work(&chan->common.wanpipe_work);
-	}
-}
-
-
-/*========================================================
- * fr_bh
- *
- * Description:
- *	Frame relay receive BH handler. 
- *	Dequeue data from the BH circular 
- *	buffer and pass it up the API sock.
- *       	
- * Rationale: 
- *	This fuction is used to offload the 
- *	rx_interrupt during API operation mode.  
- *	The fr_bh() function executes for each 
- *	dlci/interface.  
- * 
- *      Once receive interrupt copies data from the
- *      card into an skb buffer, the skb buffer
- *  	is appended to a circular BH buffer.
- *  	Then the interrupt kicks fr_bh() to finish the
- *      job at a later time (not within the interrupt).
- *       
- * Usage:
- * 	Interrupts use this to defer a task to 
- *      a polling routine.
- *
- */	
-
-static void fr_bh(struct net_device * dev)
-{
-	fr_channel_t* chan = dev->priv;
-	sdla_t *card = chan->card;
-	struct sk_buff *skb;
-
-	if (atomic_read(&chan->bh_buff_used) == 0){
-		clear_bit(0, &chan->tq_working);
-		return;
-	}
-
-	while (atomic_read(&chan->bh_buff_used)){
-
-		if (chan->common.sk == NULL || chan->common.func == NULL){
-			clear_bit(0, &chan->tq_working);
-			return;
-		}
-
-		skb  = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb;
-
-		if (skb != NULL){
-
-			if (chan->common.sk == NULL || chan->common.func == NULL){
-				++card->wandev.stats.rx_dropped;
-				++chan->ifstats.rx_dropped;
-				dev_kfree_skb_any(skb);
-				fr_bh_cleanup(dev);
-				continue;
-			}
-
-			if (chan->common.func(skb,dev,chan->common.sk) != 0){
-				/* Sock full cannot send, queue us for
-                                 * another try */
-				atomic_set(&chan->common.receive_block,1);
-				return;
-			}else{
-				fr_bh_cleanup(dev);
-			}
-		}else{
-			fr_bh_cleanup(dev);
-		}
-	}	
-	clear_bit(0, &chan->tq_working);
-
-	return;
-}
-
-static int fr_bh_cleanup(struct net_device *dev)
-{
-	fr_channel_t* chan = dev->priv;
-
-	((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL;
-
-	if (chan->bh_read == (MAX_BH_BUFF-1)){
-		chan->bh_read=0;
-	}else{
-		++chan->bh_read;	
-	}
-
-	atomic_dec(&chan->bh_buff_used);
-	return 0;
-}
-
-
-/*----------------------------------------------------------------------
-               POLL BH HANDLERS AND KICK ROUTINES 
- ----------------------------------------------------------------------*/
-
-/*============================================================
- * trigger_fr_poll
- *
- * Description:
- * 	Add a fr_poll() task into a tq_scheduler bh handler
- *      for a specific dlci/interface.  This will kick
- *      the fr_poll() routine at a later time. 
- *
- * Usage:
- * 	Interrupts use this to defer a taks to 
- *      a polling routine.
- *
- */	
-static void trigger_fr_poll(struct net_device *dev)
-{
-	fr_channel_t* chan = dev->priv;
-	schedule_work(&chan->fr_poll_work);
-	return;
-}
-
-
-/*============================================================
- * fr_poll
- *	
- * Rationale:
- * 	We cannot manipulate the routing tables, or
- *      ip addresses withing the interrupt. Therefore
- *      we must perform such actons outside an interrupt 
- *      at a later time. 
- *
- * Description:	
- *	Frame relay polling routine, responsible for 
- *     	shutting down interfaces upon disconnect
- *     	and adding/removing routes. 
- *      
- * Usage:        
- * 	This function is executed for each frame relay
- * 	dlci/interface through a tq_schedule bottom half.
- *      
- *      trigger_fr_poll() function is used to kick
- *      the fr_poll routine.  
- */
-
-static void fr_poll(struct net_device *dev)
-{
-
-	fr_channel_t* chan;
-	sdla_t *card;
-	u8 check_gateway=0;
-
-	if (!dev || (chan = dev->priv) == NULL)
-		return;
-
-	card = chan->card;
-	
-	/* (Re)Configuraiton is in progress, stop what you are 
-	 * doing and get out */
-	if (test_bit(PERI_CRIT,&card->wandev.critical)){
-		return;
-	}
-
-	switch (chan->common.state){
-
-	case WAN_DISCONNECTED:
-
-		if (test_bit(DYN_OPT_ON,&chan->interface_down) &&
-		    !test_bit(DEV_DOWN, &chan->interface_down) &&
-		    dev->flags&IFF_UP){
-
-			printk(KERN_INFO "%s: Interface %s is Down.\n", 
-				card->devname,dev->name);
-			change_dev_flags(dev,dev->flags&~IFF_UP);
-			set_bit(DEV_DOWN, &chan->interface_down);
-			chan->route_flag = NO_ROUTE;
-			
-		}else{
-			if (chan->inarp != INARP_NONE)
-				process_route(dev);	
-		}
-		break;
-
-	case WAN_CONNECTED:
-
-		if (test_bit(DYN_OPT_ON,&chan->interface_down) &&
-		    test_bit(DEV_DOWN, &chan->interface_down) &&
-		    !(dev->flags&IFF_UP)){
-
-			printk(KERN_INFO "%s: Interface %s is Up.\n", 
-					card->devname,dev->name);
-
-			change_dev_flags(dev,dev->flags|IFF_UP);
-			clear_bit(DEV_DOWN, &chan->interface_down);
-			check_gateway=1;
-		}
-
-		if (chan->inarp != INARP_NONE){
-			process_route(dev);
-			check_gateway=1;
-		}
-
-		if (chan->gateway && check_gateway)
-			add_gateway(card,dev);
-
-		break;
-
-	}
-
-	return;	
-}
-
-/*==============================================================
- * check_tx_status
- *
- * Rationale:
- *	We cannot transmit from an interrupt while
- *      the if_send is transmitting data.  Therefore,
- *      we must check whether the tx buffers are
- *      begin used, before we transmit from an
- *      interrupt.	
- * 
- * Description:	
- *	Checks whether it's safe to use the transmit 
- *      buffers. 
- *
- * Usage:
- * 	ARP and UDP handling routines use this function
- *      because, they need to transmit data during
- *      an interrupt.
- */
-
-static int check_tx_status(sdla_t *card, struct net_device *dev)
-{
-
-	if (card->hw.type == SDLA_S514){
-		if (test_bit(SEND_CRIT, (void*)&card->wandev.critical) ||
-			test_bit(SEND_TXIRQ_CRIT, (void*)&card->wandev.critical)) {
-			return 1;
-		}
-	}
-
-	if (netif_queue_stopped(dev) || (card->u.f.tx_interrupts_pending))
-     		return 1; 
-
-	return 0;
-}
-
-/*===============================================================
- * move_dev_to_next
- *  
- * Description:
- *	Move the dev pointer to the next location in the
- *      link list.  Check if we are at the end of the 
- *      list, if so start from the begining.
- *
- * Usage:
- * 	Timer interrupt uses this function to efficiently
- *      step through the devices that need to send ARP data.
- *
- */
-
-struct net_device *move_dev_to_next(sdla_t *card, struct net_device *dev)
-{
-	if (card->wandev.new_if_cnt != 1){
-		if (!*((struct net_device **)dev->priv))
-			return card->wandev.dev;
-		else
-			return *((struct net_device **)dev->priv);
-	}
-	return dev;
-}
-
-/*==============================================================
- * trigger_config_fr
- *
- * Rationale:
- *	All commands must be performed inside of a  
- *      interrupt.   
- *
- * Description:
- *	Kick the config_fr() routine throught the
- *      timer interrupt.
- */
-
-
-static void trigger_config_fr (sdla_t *card)
-{
-	fr508_flags_t* flags = card->flags;
-
-	card->u.f.timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
-	flags->imask |= FR_INTR_TIMER;
-}
-
-
-/*==============================================================
- * config_fr
- *
- * Rationale:
- * 	All commands must be performed inside of a  
- *      interrupt.  
- &
- * Description:	
- * 	Configure a DLCI. This function is executed
- *      by a timer_interrupt.  The if_open() function
- *      triggers it.
- *
- * Usage:
- *	new_if() collects all data necessary to
- *      configure the DLCI. It sets the chan->dlci_ready 
- *      bit.  When the if_open() function is executed
- *      it checks this bit, and if its set it triggers
- *      the timer interrupt to execute the config_fr()
- *      function.
- */
-
-static void config_fr (sdla_t *card)
-{
-	struct net_device *dev;
-	fr_channel_t *chan;
-
-	for (dev = card->wandev.dev; dev;
-	     dev = *((struct net_device **)dev->priv)) {
-	
-		if ((chan=dev->priv) == NULL)
-			continue;
-		
-		if (!test_bit(0,&chan->config_dlci))
-			continue;
-
-		clear_bit(0,&chan->config_dlci);
-
-		/* If signalling is set to NO, then setup 
-        	 * DLCI addresses right away.  Don't have to wait for
-		 * link to connect. 
-		 */
-		if (card->wandev.signalling == WANOPT_NO){
-			printk(KERN_INFO "%s: Signalling set to NO: Mapping DLCI's\n",
-					card->wandev.name);
-			if (fr_init_dlci(card,chan)){
-				printk(KERN_INFO "%s: ERROR: Failed to configure DLCI %i !\n",
-					card->devname, chan->dlci);
-				return;
-			}
-		}
-
-		if (card->wandev.station == WANOPT_CPE) {
-	
-			update_chan_state(dev);	
-			
-			/* CPE: issue full status enquiry */
-			fr_issue_isf(card, FR_ISF_FSE);
-
-		} else {	
-			/* FR switch: activate DLCI(s) */
-	
-			/* For Switch emulation we have to ADD and ACTIVATE
-			 * the DLCI(s) that were configured with the SET_DLCI_
-			 * CONFIGURATION command. Add and Activate will fail if
-			 * DLCI specified is not included in the list.
-			 *
-			 * Also If_open is called once for each interface. But
-			 * it does not get in here for all the interface. So
-		 	 * we have to pass the entire list of DLCI(s) to add 
-			 * activate routines.  
-			 */ 
-			
-			if (!check_dlci_config (card, chan)){
-				fr_add_dlci(card, chan->dlci);
-				fr_activate_dlci(card, chan->dlci);
-			}
-		}
-
-		card->u.f.dlci_to_dev_map[chan->dlci] = dev;
-	}
-	return;
-}
-
-
-/*==============================================================
- * config_fr
- *
- * Rationale:
- *	All commands must be executed during an interrupt.
- * 
- * Description:	
- *	Trigger uncofig_fr() function through 
- *      the timer interrupt.
- *
- */
-
-static void trigger_unconfig_fr(struct net_device *dev)
-{
-	fr_channel_t *chan = dev->priv;
-	volatile sdla_t *card = chan->card;
-	unsigned long timeout;
-	fr508_flags_t* flags = card->flags;
-	int reset_critical=0;
-	
-	if (test_bit(PERI_CRIT,(void*)&card->wandev.critical)){
-		clear_bit(PERI_CRIT,(void*)&card->wandev.critical);
-		reset_critical=1;
-	}
-		
-	/* run unconfig_dlci() function 
-         * throught the timer interrupt */
-	set_bit(0,(void*)&chan->unconfig_dlci);
-	card->u.f.timer_int_enabled |= TMR_INT_ENABLED_UNCONFIG;
-	flags->imask |= FR_INTR_TIMER;
-
-	/* Wait for the command to complete */
-	timeout = jiffies;
-     	for(;;) {
-
-		if(!(card->u.f.timer_int_enabled & TMR_INT_ENABLED_UNCONFIG))
-			break;
-
-             	if (time_after(jiffies, timeout + 1 * HZ)){
-    			card->u.f.timer_int_enabled &= ~TMR_INT_ENABLED_UNCONFIG;
-			printk(KERN_INFO "%s: Failed to delete DLCI %i\n",
-				card->devname,chan->dlci);
- 			break;
-		}
-	}
-
-	if (reset_critical){
-		set_bit(PERI_CRIT,(void*)&card->wandev.critical);
-	}
-}
-
-/*==============================================================
- * unconfig_fr
- *
- * Rationale:
- *	All commands must be executed during an interrupt.
- * 
- * Description:	
- *	Remove the dlci from firmware.
- *	This funciton is used in NODE shutdown.
- */
-
-static void unconfig_fr (sdla_t *card)
-{
-	struct net_device *dev;
-	fr_channel_t *chan;
-
-	for (dev = card->wandev.dev; dev;
-	     dev = *((struct net_device **)dev->priv)){
-	
-		if ((chan=dev->priv) == NULL)
-			continue;
-		
-		if (!test_bit(0,&chan->unconfig_dlci))
-			continue;
-
-		clear_bit(0,&chan->unconfig_dlci);
-
-		if (card->wandev.station == WANOPT_NODE){
-			printk(KERN_INFO "%s: Unconfiguring DLCI %i\n",
-					card->devname,chan->dlci);
-			fr_delete_dlci(card,chan->dlci);
-		}
-		card->u.f.dlci_to_dev_map[chan->dlci] = NULL;
-	}
-}
-
-static int setup_fr_header(struct sk_buff *skb, struct net_device* dev,
-			   char op_mode)
-{
-	fr_channel_t *chan=dev->priv;
-
-	if (op_mode == WANPIPE) {
-		chan->fr_header[0]=Q922_UI;
-		
-		switch (htons(skb->protocol)){
-		case ETH_P_IP:
-			chan->fr_header[1]=NLPID_IP;
-			break;
-		default:
-			return -EINVAL;
-		}
-			
-		return 2;
-	}
-
-	/* If we are in bridging mode, we must apply
-	 * an Ethernet header
-	 */
-	if (op_mode == BRIDGE || op_mode == BRIDGE_NODE) {
-		/* Encapsulate the packet as a bridged Ethernet frame. */
-#ifdef DEBUG
-		printk(KERN_INFO "%s: encapsulating skb for frame relay\n", 
-			dev->name);
-#endif
-		chan->fr_header[0] = 0x03;
-		chan->fr_header[1] = 0x00;
-		chan->fr_header[2] = 0x80;
-		chan->fr_header[3] = 0x00;
-		chan->fr_header[4] = 0x80;
-		chan->fr_header[5] = 0xC2;
-		chan->fr_header[6] = 0x00;
-		chan->fr_header[7] = 0x07;
-
-		/* Yuck. */
-		skb->protocol = ETH_P_802_3;
-		return 8;
-	}
-		
-	return 0;
-}
-
-
-static int check_dlci_config (sdla_t *card, fr_channel_t *chan)
-{
-	fr_mbox_t* mbox = card->mbox;
-	int err=0;
-	fr_conf_t *conf=NULL;
-	unsigned short dlci_num = chan->dlci;
-	int dlci_offset=0;
-	struct net_device *dev = NULL;
-	
-	mbox->cmd.command = FR_READ_CONFIG;
-	mbox->cmd.length = 0;
-	mbox->cmd.dlci = dlci_num; 	
-
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	
-	if (err == CMD_OK){
-		return 0;
-	}
-
-	for (dev = card->wandev.dev; dev;
-	     dev=*((struct net_device **)dev->priv))
-		set_chan_state(dev,WAN_DISCONNECTED);
-	
-	printk(KERN_INFO "DLCI %i Not configured, configuring\n",dlci_num);
-	
-	mbox->cmd.command = FR_COMM_DISABLE;
-	mbox->cmd.length = 0;
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	if (err != CMD_OK){
-		fr_event(card, err, mbox);
-		return 2;
-	}
-
-	printk(KERN_INFO "Disabled Communications \n");
-	
-	mbox->cmd.command = FR_READ_CONFIG;
-	mbox->cmd.length = 0;
-	mbox->cmd.dlci = 0; 	
-
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	
-	if (err != CMD_OK){
-		fr_event(card, err, mbox);
-		return 2;
-	}
-	
-	conf = (fr_conf_t *)mbox->data;
-
-	dlci_offset=0;
-	for (dev = card->wandev.dev; dev;
-	     dev = *((struct net_device **)dev->priv)) {
-		fr_channel_t *chan_tmp = dev->priv;
-		conf->dlci[dlci_offset] = chan_tmp->dlci;		
-		dlci_offset++;
-	}
-	
-	printk(KERN_INFO "Got Fr configuration Buffer Length is %x Dlci %i Dlci Off %i\n",
-		mbox->cmd.length,
-		mbox->cmd.length > 0x20 ? conf->dlci[0] : -1, 
-		dlci_offset );
-	
-	mbox->cmd.length = 0x20 + dlci_offset*2;
-
-	mbox->cmd.command = FR_SET_CONFIG;
-	mbox->cmd.dlci = 0; 
-
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-
-	if (err != CMD_OK){
-		fr_event(card, err, mbox);
-		return 2;
-	}
-
-	initialize_rx_tx_buffers (card);
-
-	
-	printk(KERN_INFO "Configuraiton Succeded for new DLCI %i\n",dlci_num);
-
-	if (fr_comm_enable (card)){
-		return 2;
-	}
-
-	printk(KERN_INFO "Enabling Communications \n");
-
-	for (dev = card->wandev.dev; dev;
-	     dev = *((struct net_device **)dev->priv)) {
-		fr_channel_t *chan_tmp = dev->priv;
-		fr_init_dlci(card,chan_tmp);
-		fr_add_dlci(card, chan_tmp->dlci);
-		fr_activate_dlci(card, chan_tmp->dlci);
-	}
-
-	printk(KERN_INFO "END OF CONFIGURAITON %i\n",dlci_num);
-	
-	return 1;
-}
-
-static void initialize_rx_tx_buffers (sdla_t *card)
-{
-	fr_buf_info_t* buf_info;
-	
-	if (card->hw.type == SDLA_S514) {
-	
-                buf_info = (void*)(card->hw.dpmbase + FR_MB_VECTOR +
-			FR508_RXBC_OFFS);
-
-                card->rxmb = (void*)(buf_info->rse_next + card->hw.dpmbase);
-
-                card->u.f.rxmb_base =
-                        (void*)(buf_info->rse_base + card->hw.dpmbase); 
-
-                card->u.f.rxmb_last =
-                        (void*)(buf_info->rse_base +
-                        (buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) +
-                        card->hw.dpmbase);
-	}else{	
-		buf_info = (void*)(card->hw.dpmbase + FR508_RXBC_OFFS);
-
-		card->rxmb = (void*)(buf_info->rse_next -
-			FR_MB_VECTOR + card->hw.dpmbase);
-		
-		card->u.f.rxmb_base =
-			(void*)(buf_info->rse_base -
-			FR_MB_VECTOR + card->hw.dpmbase);
-		
-		card->u.f.rxmb_last =
-			(void*)(buf_info->rse_base +
-			(buf_info->rse_num - 1) * sizeof(fr_rx_buf_ctl_t) -
-			FR_MB_VECTOR + card->hw.dpmbase);
-	}
-
-	card->u.f.rx_base = buf_info->buf_base;
-	card->u.f.rx_top  = buf_info->buf_top;
-
-	card->u.f.tx_interrupts_pending = 0;
-
-	return;
-}
-
-	
-
-MODULE_LICENSE("GPL");
-
-/****** End *****************************************************************/
diff --git a/drivers/net/wan/sdla_ft1.c b/drivers/net/wan/sdla_ft1.c
deleted file mode 100644
index 9d6528a..0000000
--- a/drivers/net/wan/sdla_ft1.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/*****************************************************************************
-* sdla_chdlc.c	WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module.
-*
-* Authors: 	Nenad Corbic <ncorbic@sangoma.com>
-*		Gideon Hack  
-*
-* Copyright:	(c) 1995-1999 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.
-* ============================================================================
-* Sep 30, 1999  Nenad Corbic    Fixed dynamic IP and route setup.
-* Sep 23, 1999  Nenad Corbic    Added SMP support, fixed tracing 
-* Sep 13, 1999  Nenad Corbic	Split up Port 0 and 1 into separate devices.
-* Jun 02, 1999  Gideon Hack     Added support for the S514 adapter.
-* Oct 30, 1998	Jaspreet Singh	Added Support for CHDLC API (HDLC STREAMING).
-* Oct 28, 1998	Jaspreet Singh	Added Support for Dual Port CHDLC.
-* Aug 07, 1998	David Fong	Initial version.
-*****************************************************************************/
-
-#include <linux/module.h>
-#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/slab.h>		/* kmalloc(), kfree() */
-#include <linux/wanrouter.h>	/* WAN router definitions */
-#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
-#include <linux/if_arp.h>	/* ARPHRD_* defines */
-#include <linux/jiffies.h>	/* time_after() macro */
-
-#include <linux/inetdevice.h>
-#include <asm/uaccess.h>
-
-#include <linux/in.h>		/* sockaddr_in */
-#include <linux/inet.h>	
-#include <linux/if.h>
-#include <asm/byteorder.h>	/* htons(), etc. */
-#include <linux/sdlapci.h>
-#include <asm/io.h>
-
-#include <linux/sdla_chdlc.h>		/* CHDLC firmware API definitions */
-
-/****** Defines & Macros ****************************************************/
-
-/* reasons for enabling the timer interrupt on the adapter */
-#define TMR_INT_ENABLED_UDP   	0x0001
-#define TMR_INT_ENABLED_UPDATE	0x0002
- 
-#define	CHDLC_DFLT_DATA_LEN	1500		/* default MTU */
-#define CHDLC_HDR_LEN		1
-
-#define IFF_POINTTOPOINT 0x10
-
-#define WANPIPE 0x00
-#define API	0x01
-#define CHDLC_API 0x01
-
-#define PORT(x)   (x == 0 ? "PRIMARY" : "SECONDARY" )
-
- 
-/******Data Structures*****************************************************/
-
-/* This structure is placed in the private data area of the device structure.
- * The card structure used to occupy the private area but now the following 
- * structure will incorporate the card structure along with CHDLC specific data
- */
-
-typedef struct chdlc_private_area
-{
-	struct net_device *slave;
-	sdla_t		*card;
-	int 		TracingEnabled;		/* For enabling Tracing */
-	unsigned long 	curr_trace_addr;	/* Used for Tracing */
-	unsigned long 	start_trace_addr;
-	unsigned long 	end_trace_addr;
-	unsigned long 	base_addr_trace_buffer;
-	unsigned long 	end_addr_trace_buffer;
-	unsigned short 	number_trace_elements;
-	unsigned  	available_buffer_space;
-	unsigned long 	router_start_time;
-	unsigned char 	route_status;
-	unsigned char 	route_removed;
-	unsigned long 	tick_counter;		/* For 5s timeout counter */
-	unsigned long 	router_up_time;
-        u32             IP_address;		/* IP addressing */
-        u32             IP_netmask;
-	unsigned char  mc;			/* Mulitcast support on/off */
-	unsigned short udp_pkt_lgth;		/* udp packet processing */
-	char udp_pkt_src;
-	char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
-	unsigned short timer_int_enabled;
-	char update_comms_stats;		/* updating comms stats */
-	//FIXME: add driver stats as per frame relay!
-
-} chdlc_private_area_t;
-
-/* Route Status options */
-#define NO_ROUTE	0x00
-#define ADD_ROUTE	0x01
-#define ROUTE_ADDED	0x02
-#define REMOVE_ROUTE	0x03
-
-
-/****** Function Prototypes *************************************************/
-/* WAN link driver entry points. These are called by the WAN router module. */
-static int wpft1_exec (struct sdla *card, void *u_cmd, void *u_data);
-static int chdlc_read_version (sdla_t* card, char* str);
-static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
-
-/****** Public Functions ****************************************************/
-
-/*============================================================================
- * Cisco HDLC protocol initialization routine.
- *
- * This routine is called by the main WANPIPE module during setup.  At this
- * point adapter is completely initialized and 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 wpft1_init (sdla_t* card, wandev_conf_t* conf)
-{
-	unsigned char port_num;
-	int err;
-
-	union
-		{
-		char str[80];
-		} u;
-	volatile CHDLC_MAILBOX_STRUCT* mb;
-	CHDLC_MAILBOX_STRUCT* mb1;
-	unsigned long timeout;
-
-	/* Verify configuration ID */
-	if (conf->config_id != WANCONFIG_CHDLC) {
-		printk(KERN_INFO "%s: invalid configuration ID %u!\n",
-				  card->devname, conf->config_id);
-		return -EINVAL;
-	}
-
-	/* Use primary port */
-	card->u.c.comm_port = 0;
-	
-
-	/* Initialize protocol-specific fields */
-	if(card->hw.type != SDLA_S514){
-		card->mbox  = (void *) card->hw.dpmbase;
-	}else{ 
-		card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
-	}
-
-	mb = mb1 = card->mbox;
-
-	if (!card->configured){
-
-		/* The board will place an 'I' in the return code to indicate that it is
-	   	ready to accept commands.  We expect this to be completed in less
-           	than 1 second. */
-
-		timeout = jiffies;
-		while (mb->return_code != 'I')	/* Wait 1s for board to initialize */
-			if (time_after(jiffies, timeout + 1*HZ)) break;
-
-		if (mb->return_code != 'I') {
-			printk(KERN_INFO
-				"%s: Initialization not completed by adapter\n",
-				card->devname);
-			printk(KERN_INFO "Please contact Sangoma representative.\n");
-			return -EIO;
-		}
-	}
-
-	/* 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 (chdlc_read_version(card, u.str))
-		return -EIO;
-
-	printk(KERN_INFO "%s: Running FT1 Configuration firmware v%s\n",
-		card->devname, u.str); 
-
-	card->isr			= NULL;
-	card->poll			= NULL;
-	card->exec			= &wpft1_exec;
-	card->wandev.update		= NULL;
- 	card->wandev.new_if		= NULL;
-	card->wandev.del_if		= NULL;
-	card->wandev.state		= WAN_DUALPORT;
-	card->wandev.udp_port   	= conf->udp_port;
-
-	card->wandev.new_if_cnt = 0;
-
-	/* This is for the ports link state */
-	card->u.c.state = WAN_DISCONNECTED;
-	
-	/* reset the number of times the 'update()' proc has been called */
-	card->u.c.update_call_count = 0;
-	
-	card->wandev.ttl = 0x7F;
-	card->wandev.interface = 0; 
-
-	card->wandev.clocking = 0;
-
-	port_num = card->u.c.comm_port;
-
-	/* Setup Port Bps */
-
-       	card->wandev.bps = 0;
-
-	card->wandev.mtu = MIN_LGTH_CHDLC_DATA_CFG;
-
-	/* Set up the interrupt status area */
-	/* Read the CHDLC Configuration and obtain: 
-	 *	Ptr to shared memory infor struct
-         * Use this pointer to calculate the value of card->u.c.flags !
- 	 */
-	mb1->buffer_length = 0;
-	mb1->command = READ_CHDLC_CONFIGURATION;
-	err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
-	if(err != COMMAND_OK) {
-		chdlc_error(card, err, mb1);
-		return -EIO;
-	}
-
-	if(card->hw.type == SDLA_S514){
-               	card->u.c.flags = (void *)(card->hw.dpmbase +
-               		(((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
-			ptr_shared_mem_info_struct));
-        }else{
-                card->u.c.flags = (void *)(card->hw.dpmbase +
-                        (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
-			ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
-	}
-
-	card->wandev.state = WAN_FT1_READY;
-	printk(KERN_INFO "%s: FT1 Config Ready !\n",card->devname);
-
-	return 0;
-}
-
-static int wpft1_exec(sdla_t *card, void *u_cmd, void *u_data)
-{
-	CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
-	int len;
-
-	if (copy_from_user((void*)&mbox->command, u_cmd, sizeof(ft1_exec_cmd_t))){
-		return -EFAULT;
-	}
-
-	len = mbox->buffer_length;
-
-	if (len) {
-		if( copy_from_user((void*)&mbox->data, u_data, len)){
-			return -EFAULT;
-		}
-	}
-
-	/* execute command */
-	if (!sdla_exec(mbox)){
-		return -EIO;
-	}
-
-	/* return result */
-	if( copy_to_user(u_cmd, (void*)&mbox->command, sizeof(ft1_exec_cmd_t))){
-		return -EFAULT;
-	}
-
-	len = mbox->buffer_length;
-
-	if (len && u_data && copy_to_user(u_data, (void*)&mbox->data, len)){
-		return -EFAULT;
-	}
-
-	return 0;
-
-}
-
-/*============================================================================
- * 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);
-}
-
-/*============================================================================
- * 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)
-{
-	unsigned cmd = mb->command;
-
-	switch (err) {
-
-	case CMD_TIMEOUT:
-		printk(KERN_ERR "%s: command 0x%02X timed out!\n",
-			card->devname, cmd);
-		break;
-
-	case S514_BOTH_PORTS_SAME_CLK_MODE:
-		if(cmd == SET_CHDLC_CONFIGURATION) {
-			printk(KERN_INFO
-			 "%s: Configure both ports for the same clock source\n",
-				card->devname);
-			break;
-		}
-
-	default:
-		printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
-			card->devname, cmd, err);
-	}
-
-	return 0;
-}
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/net/wan/sdla_ppp.c b/drivers/net/wan/sdla_ppp.c
deleted file mode 100644
index a4b489c..0000000
--- a/drivers/net/wan/sdla_ppp.c
+++ /dev/null
@@ -1,3430 +0,0 @@
-/*****************************************************************************
-* sdla_ppp.c	WANPIPE(tm) Multiprotocol WAN Link Driver. PPP module.
-*
-* Author: 	Nenad Corbic <ncorbic@sangoma.com>
-*
-* Copyright:	(c) 1995-2001 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.
-* ============================================================================
-* Feb 28, 2001  Nenad Corbic	o Updated if_tx_timeout() routine for 
-* 				  2.4.X kernels.
-* Nov 29, 2000  Nenad Corbic	o Added the 2.4.x kernel support:
-* 				  get_ip_address() function has moved
-* 				  into the ppp_poll() routine. It cannot
-* 				  be called from an interrupt.
-* Nov 07, 2000  Nenad Corbic	o Added security features for UDP debugging:
-*                                 Deny all and specify allowed requests.
-* May 02, 2000  Nenad Corbic	o Added the dynamic interface shutdown
-*                                 option. When the link goes down, the
-*                                 network interface IFF_UP flag is reset.
-* Mar 06, 2000  Nenad Corbic	o Bug Fix: corrupted mbox recovery.
-* Feb 25, 2000  Nenad Corbic    o Fixed the FT1 UDP debugger problem.
-* Feb 09, 2000  Nenad Coribc    o Shutdown bug fix. update() was called
-*                                 with NULL dev pointer: no check.
-* Jan 24, 2000  Nenad Corbic    o Disabled use of CMD complete inter.
-* Dev 15, 1999  Nenad Corbic    o Fixed up header files for 2.0.X kernels
-* Oct 25, 1999  Nenad Corbic    o Support for 2.0.X kernels
-*                                 Moved dynamic route processing into 
-*                                 a polling routine.
-* Oct 07, 1999  Nenad Corbic    o Support for S514 PCI card.  
-*               Gideon Hack     o UPD and Updates executed using timer interrupt
-* Sep 10, 1999  Nenad Corbic    o Fixed up the /proc statistics
-* Jul 20, 1999  Nenad Corbic    o Remove the polling routines and use 
-*                                 interrupts instead.
-* Sep 17, 1998	Jaspreet Singh	o Updates for 2.2.X Kernels.
-* Aug 13, 1998	Jaspreet Singh	o Improved Line Tracing.
-* Jun 22, 1998	David Fong	o Added remote IP address assignment
-* Mar 15, 1998	Alan Cox	o 2.1.8x basic port.
-* Apr 16, 1998	Jaspreet Singh	o using htons() for the IPX protocol.
-* Dec 09, 1997	Jaspreet Singh	o Added PAP and CHAP.
-*				o Implemented new routines like 
-*				  ppp_set_inbnd_auth(), ppp_set_outbnd_auth(),
-*				  tokenize() and strstrip().
-* Nov 27, 1997	Jaspreet Singh	o Added protection against enabling of irqs 
-*				  while they have been disabled.
-* Nov 24, 1997  Jaspreet Singh  o Fixed another RACE condition caused by
-*                                 disabling and enabling of irqs.
-*                               o Added new counters for stats on disable/enable
-*                                 IRQs.
-* Nov 10, 1997	Jaspreet Singh	o Initialized 'skb->mac.raw' to 'skb->data'
-*				  before every netif_rx().
-*				o Free up the device structure in del_if().
-* Nov 07, 1997	Jaspreet Singh	o Changed the delay to zero for Line tracing
-*				  command.
-* Oct 20, 1997 	Jaspreet Singh	o Added hooks in for Router UP time.
-* Oct 16, 1997	Jaspreet Singh  o The critical flag is used to maintain flow
-*				  control by avoiding RACE conditions.  The 
-*				  cli() and restore_flags() are taken out.
-*				  A new structure, "ppp_private_area", is added 
-*				  to provide Driver Statistics.   
-* Jul 21, 1997 	Jaspreet Singh	o Protected calls to sdla_peek() by adding 
-*				  save_flags(), cli() and restore_flags().
-* Jul 07, 1997	Jaspreet Singh  o Added configurable TTL for UDP packets
-*				o Added ability to discard mulitcast and
-*				  broacast source addressed packets.
-* Jun 27, 1997 	Jaspreet Singh	o Added FT1 monitor capabilities
-*				  New case (0x25) statement in if_send routine.
-*				  Added a global variable rCount to keep track
-*				  of FT1 status enabled on the board.
-* May 22, 1997	Jaspreet Singh	o Added change in the PPP_SET_CONFIG command for
-*				508 card to reflect changes in the new 
-*				ppp508.sfm for supporting:continous transmission
-*				of Configure-Request packets without receiving a
-*				reply 				
-*				OR-ed 0x300 to conf_flags 
-*			        o Changed connect_tmout from 900 to 0
-* May 21, 1997	Jaspreet Singh  o Fixed UDP Management for multiple boards
-* Apr 25, 1997  Farhan Thawar    o added UDP Management stuff
-* Mar 11, 1997  Farhan Thawar   Version 3.1.1
-*                                o fixed (+1) bug in rx_intr()
-*                                o changed if_send() to return 0 if
-*                                  wandev.critical() is true
-*                                o free socket buffer in if_send() if
-*                                  returning 0 
-* Jan 15, 1997	Gene Kozin	Version 3.1.0
-*				 o implemented exec() entry point
-* Jan 06, 1997	Gene Kozin	Initial version.
-*****************************************************************************/
-
-#include <linux/module.h>
-#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/slab.h>	/* kmalloc(), kfree() */
-#include <linux/wanrouter.h>	/* WAN router definitions */
-#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
-#include <linux/if_arp.h>	/* ARPHRD_* defines */
-#include <asm/byteorder.h>	/* htons(), etc. */
-#include <linux/in.h>		/* sockaddr_in */
-#include <linux/jiffies.h>	/* time_after() macro */
-
-
-#include <asm/uaccess.h>
-#include <linux/inetdevice.h>
-#include <linux/netdevice.h>
-
-#include <linux/if.h>
-#include <linux/sdla_ppp.h>		/* PPP firmware API definitions */
-#include <linux/sdlasfm.h>		/* S514 Type Definition */
-/****** Defines & Macros ****************************************************/
-
-#define	PPP_DFLT_MTU	1500		/* default MTU */
-#define	PPP_MAX_MTU	4000		/* maximum MTU */
-#define PPP_HDR_LEN	1
-
-#define MAX_IP_ERRORS 100 
-
-#define	CONNECT_TIMEOUT	(90*HZ)		/* link connection timeout */
-#define	HOLD_DOWN_TIME	(5*HZ)		/* link hold down time : Changed from 30 to 5 */
-
-/* For handle_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)))
-
-/* Macro for enabling/disabling debugging comments */
-//#define NEX_DEBUG
-#ifdef NEX_DEBUG
-#define NEX_PRINTK(format, a...) printk(format, ## a)
-#else
-#define NEX_PRINTK(format, a...)
-#endif /* NEX_DEBUG */ 
-
-#define DCD(a)   ( a & 0x08 ? "HIGH" : "LOW" )
-#define CTS(a)   ( a & 0x20 ? "HIGH" : "LOW" )
-#define LCP(a)   ( a == 0x09 ? "OPEN" : "CLOSED" )
-#define IP(a)    ( a == 0x09 ? "ENABLED" : "DISABLED" )
-
-#define TMR_INT_ENABLED_UPDATE  	0x01
-#define TMR_INT_ENABLED_PPP_EVENT	0x02
-#define TMR_INT_ENABLED_UDP		0x04
-#define TMR_INT_ENABLED_CONFIG		0x20
-
-/* Set Configuraton Command Definitions */
-#define PERCENT_TX_BUFF			60
-#define TIME_BETWEEN_CONF_REQ  		30
-#define TIME_BETWEEN_PAP_CHAP_REQ	30
-#define WAIT_PAP_CHAP_WITHOUT_REPLY     300
-#define WAIT_AFTER_DCD_CTS_LOW          5
-#define TIME_DCD_CTS_LOW_AFTER_LNK_DOWN 10
-#define WAIT_DCD_HIGH_AFTER_ENABLE_COMM 900
-#define MAX_CONF_REQ_WITHOUT_REPLY      10
-#define MAX_TERM_REQ_WITHOUT_REPLY      2
-#define NUM_CONF_NAK_WITHOUT_REPLY      5
-#define NUM_AUTH_REQ_WITHOUT_REPLY      10
-
-#define END_OFFSET 0x1F0
-
-
-/******Data Structures*****************************************************/
-
-/* This structure is placed in the private data area of the device structure.
- * The card structure used to occupy the private area but now the following 
- * structure will incorporate the card structure along with PPP specific data
- */
-  
-typedef struct ppp_private_area
-{
-	struct net_device *slave;
-	sdla_t* card;	
-	unsigned long router_start_time;	/*router start time in sec */
-	unsigned long tick_counter;		/*used for 5 second counter*/
-	unsigned mc;				/*multicast support on or off*/
-	unsigned char enable_IPX;
-	unsigned long network_number;
-	unsigned char pap;
-	unsigned char chap;
-	unsigned char sysname[31];		/* system name for in-bnd auth*/
-	unsigned char userid[511];		/* list of user ids */
-	unsigned char passwd[511];		/* list of passwords */
-	unsigned protocol;			/* SKB Protocol */
-	u32 ip_local;				/* Local IP Address */
-	u32 ip_remote;				/* remote IP Address */
-
-	u32 ip_local_tmp;
-	u32 ip_remote_tmp;
-	
-	unsigned char timer_int_enabled;	/* Who enabled the timer inter*/
-	unsigned char update_comms_stats;	/* Used by update function */
-	unsigned long curr_trace_addr;		/* Trace information */
-	unsigned long start_trace_addr;
-	unsigned long end_trace_addr;
-
-	unsigned char interface_down;		/* Brind down interface when channel 
-                                                   goes down */
-	unsigned long config_wait_timeout;	/* After if_open() if in dynamic if mode,
-						   wait a few seconds before configuring */
-	
-	unsigned short udp_pkt_lgth;
-	char  udp_pkt_src;
-      	char  udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
-
-	/* PPP specific statistics */
-
-	if_send_stat_t if_send_stat;
-	rx_intr_stat_t rx_intr_stat;
-	pipe_mgmt_stat_t pipe_mgmt_stat;
-
-	unsigned long router_up_time; 
-
-	/* Polling work queue entry. Each interface
-         * has its own work queue entry, which is used
-         * to defer events from the interrupt */
-	struct work_struct poll_work;
-	struct timer_list poll_delay_timer;
-
-	u8 gateway;
-	u8 config_ppp;
-	u8 ip_error;
-	
-}ppp_private_area_t;
-
-/* variable for keeping track of enabling/disabling FT1 monitor status */
-static int rCount = 0;
-
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-/****** Function Prototypes *************************************************/
-
-/* WAN link driver entry points. These are called by the WAN router module. */
-static int update(struct wan_device *wandev);
-static int new_if(struct wan_device *wandev, struct net_device *dev,
-		  wanif_conf_t *conf);
-static int del_if(struct wan_device *wandev, struct net_device *dev);
-
-/* WANPIPE-specific entry points */
-static int wpp_exec (struct sdla *card, void *u_cmd, void *u_data);
-
-/* Network device interface */
-static int if_init(struct net_device *dev);
-static int if_open(struct net_device *dev);
-static int if_close(struct net_device *dev);
-static int if_header(struct sk_buff *skb, struct net_device *dev,
-		     unsigned short type, 
-		     void *daddr, void *saddr, unsigned len);
-
-static void if_tx_timeout(struct net_device *dev);
-
-static int if_rebuild_hdr(struct sk_buff *skb);
-static struct net_device_stats *if_stats(struct net_device *dev);
-static int if_send(struct sk_buff *skb, struct net_device *dev);
-
-
-/* PPP firmware interface functions */
-static int ppp_read_version(sdla_t *card, char *str);
-static int ppp_set_outbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area);
-static int ppp_set_inbnd_auth(sdla_t *card, ppp_private_area_t *ppp_priv_area);
-static int ppp_configure(sdla_t *card, void *data);
-static int ppp_set_intr_mode(sdla_t *card, unsigned char mode);
-static int ppp_comm_enable(sdla_t *card);
-static int ppp_comm_disable(sdla_t *card);
-static int ppp_comm_disable_shutdown(sdla_t *card);
-static int ppp_get_err_stats(sdla_t *card);
-static int ppp_send(sdla_t *card, void *data, unsigned len, unsigned proto);
-static int ppp_error(sdla_t *card, int err, ppp_mbox_t *mb);
-
-static void wpp_isr(sdla_t *card);
-static void rx_intr(sdla_t *card);
-static void event_intr(sdla_t *card);
-static void timer_intr(sdla_t *card);
-
-/* Background polling routines */
-static void process_route(sdla_t *card);
-static void retrigger_comm(sdla_t *card);
-
-/* Miscellaneous functions */
-static int read_info( sdla_t *card );
-static int read_connection_info (sdla_t *card);
-static void remove_route( sdla_t *card );
-static int config508(struct net_device *dev, sdla_t *card);
-static void show_disc_cause(sdla_t * card, unsigned cause);
-static int reply_udp( unsigned char *data, unsigned int mbox_len );
-static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev, 
-				ppp_private_area_t *ppp_priv_area);
-static void init_ppp_tx_rx_buff( sdla_t *card );
-static int intr_test( sdla_t *card );
-static int udp_pkt_type( struct sk_buff *skb , sdla_t *card);
-static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area);
-static void init_global_statistics( sdla_t *card );
-static int tokenize(char *str, char **tokens);
-static char* strstrip(char *str, char *s);
-static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev,
-				struct sk_buff *skb);
-
-static int config_ppp (sdla_t *);
-static void ppp_poll(struct net_device *dev);
-static void trigger_ppp_poll(struct net_device *dev);
-static void ppp_poll_delay (unsigned long dev_ptr);
-
-
-static int Read_connection_info;
-static int Intr_test_counter;
-static unsigned short available_buffer_space;
-
-
-/* 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_PX, 
-			 unsigned long network_number, unsigned short proto);
-
-/* Lock Functions */
-static void s508_lock (sdla_t *card, unsigned long *smp_flags);
-static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
-
-static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
-                                struct sk_buff *skb, struct net_device* dev,
-                                ppp_private_area_t* ppp_priv_area );
-static unsigned short calc_checksum (char *data, int len);
-static void disable_comm (sdla_t *card);
-static int detect_and_fix_tx_bug (sdla_t *card);
-
-/****** Public Functions ****************************************************/
-
-/*============================================================================
- * PPP protocol initialization routine.
- *
- * This routine is called by the main WANPIPE module during setup.  At this
- * point adapter is completely initialized and 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 wpp_init(sdla_t *card, wandev_conf_t *conf)
-{
-	ppp_flags_t *flags;
-	union
-	{
-		char str[80];
-	} u;
-
-	/* Verify configuration ID */
-	if (conf->config_id != WANCONFIG_PPP) {
-		
-		printk(KERN_INFO "%s: invalid configuration ID %u!\n",
-			card->devname, conf->config_id);
-		return -EINVAL;
-
-	}
-
-	/* Initialize miscellaneous pointers to structures on the adapter */
-	switch (card->hw.type) {
-
-		case SDLA_S508:
-			card->mbox =(void*)(card->hw.dpmbase + PPP508_MB_OFFS);
-			card->flags=(void*)(card->hw.dpmbase + PPP508_FLG_OFFS);
-			break;
-		
-		case SDLA_S514:
-			card->mbox =(void*)(card->hw.dpmbase + PPP514_MB_OFFS);
-			card->flags=(void*)(card->hw.dpmbase + PPP514_FLG_OFFS);
-			break;
-
-		default:
-			return -EINVAL;
-
-	}
-	flags = card->flags;
-
-	/* 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 (ppp_read_version(card, NULL) || ppp_read_version(card, u.str))
-		return -EIO;
-	
-	printk(KERN_INFO "%s: running PPP firmware v%s\n",card->devname, u.str); 
-	/* Adjust configuration and set defaults */
-	card->wandev.mtu = (conf->mtu) ?
-		min_t(unsigned int, conf->mtu, PPP_MAX_MTU) : PPP_DFLT_MTU;
-
-	card->wandev.bps	= conf->bps;
-	card->wandev.interface	= conf->interface;
-	card->wandev.clocking	= conf->clocking;
-	card->wandev.station	= conf->station;
-	card->isr		= &wpp_isr;
-	card->poll		= NULL; 
-	card->exec		= &wpp_exec;
-	card->wandev.update	= &update;
-	card->wandev.new_if	= &new_if;
-	card->wandev.del_if	= &del_if;
-        card->wandev.udp_port   = conf->udp_port;
-	card->wandev.ttl	= conf->ttl;
-	card->wandev.state      = WAN_DISCONNECTED;
-	card->disable_comm	= &disable_comm;
-	card->irq_dis_if_send_count = 0;
-        card->irq_dis_poll_count = 0;
-	card->u.p.authenticator = conf->u.ppp.authenticator;
-	card->u.p.ip_mode 	= conf->u.ppp.ip_mode ?
-				 conf->u.ppp.ip_mode : WANOPT_PPP_STATIC;
-        card->TracingEnabled    = 0;
-	Read_connection_info    = 1;
-
-	/* initialize global statistics */
-	init_global_statistics( card );
-
-
-
-	if (!card->configured){
-		int err;
-
-		Intr_test_counter = 0;
-		err = intr_test(card);
-
-		if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
-			printk("%s: Interrupt Test Failed, Counter: %i\n", 
-				card->devname, Intr_test_counter);
-			printk( "%s: Please choose another interrupt\n",card->devname);
-			return -EIO;
-		}
-		
-		printk(KERN_INFO "%s: Interrupt Test Passed, Counter: %i\n", 
-			card->devname, Intr_test_counter);
-		card->configured = 1;
-	}
-
-	ppp_set_intr_mode(card, PPP_INTR_TIMER); 
-
-	/* Turn off the transmit and timer interrupt */
-	flags->imask &= ~PPP_INTR_TIMER;
-
-	printk(KERN_INFO "\n");
-
-	return 0;
-}
-
-/******* WAN Device Driver Entry Points *************************************/
-
-/*============================================================================
- * Update device status & statistics.
- */
-static int update(struct wan_device *wandev)
-{
-	sdla_t* card = wandev->private;
- 	struct net_device* dev;
-        volatile ppp_private_area_t *ppp_priv_area;
-	ppp_flags_t *flags = card->flags;
-	unsigned long timeout;
-
-	/* sanity checks */
-	if ((wandev == NULL) || (wandev->private == NULL))
-		return -EFAULT;
-	
-	if (wandev->state == WAN_UNCONFIGURED)
-		return -ENODEV;
-	
-	/* Shutdown bug fix. This function can be
-         * called with NULL dev pointer during
-         * shutdown 
-	 */
-	if ((dev=card->wandev.dev) == NULL){
-		return -ENODEV;
-	}
-
-	if ((ppp_priv_area=dev->priv) == NULL){
-		return -ENODEV;
-	}
-	
-	ppp_priv_area->update_comms_stats = 2;
-	ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
-	flags->imask |= PPP_INTR_TIMER;	
-	
-	/* wait a maximum of 1 second for the statistics to be updated */ 
-        timeout = jiffies;
-        for(;;) {
-		if(ppp_priv_area->update_comms_stats == 0){
-			break;
-		}
-                if (time_after(jiffies, timeout + 1 * HZ)){
-    			ppp_priv_area->update_comms_stats = 0;
- 			ppp_priv_area->timer_int_enabled &=
-				~TMR_INT_ENABLED_UPDATE; 
- 			return -EAGAIN;
-		}
-        }
-
-	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(struct wan_device *wandev, struct net_device *dev,
-		  wanif_conf_t *conf)
-{
-	sdla_t *card = wandev->private;
-	ppp_private_area_t *ppp_priv_area;
-
-	if (wandev->ndev)
-		return -EEXIST;
-	
-
-	printk(KERN_INFO "%s: Configuring Interface: %s\n",
-			card->devname, conf->name);
-
-	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 */
-	ppp_priv_area = kmalloc(sizeof(ppp_private_area_t), GFP_KERNEL);
-	
-	if( ppp_priv_area == NULL )
-		return	-ENOMEM;
-	
-	memset(ppp_priv_area, 0, sizeof(ppp_private_area_t));
-	
-	ppp_priv_area->card = card; 
-	
-	/* initialize data */
-	strcpy(card->u.p.if_name, conf->name);
-
-	/* initialize data in ppp_private_area structure */
-	
-	init_ppp_priv_struct( ppp_priv_area );
-
-	ppp_priv_area->mc = conf->mc;
-	ppp_priv_area->pap = conf->pap;
-	ppp_priv_area->chap = conf->chap;
-
-	/* Option to bring down the interface when 
-         * the link goes down */
-	if (conf->if_down){
-		set_bit(DYN_OPT_ON,&ppp_priv_area->interface_down);
-		printk("%s: Dynamic interface configuration enabled\n",
-			card->devname);
-	} 
-
-	/* If no user ids are specified */
-	if(!strlen(conf->userid) && (ppp_priv_area->pap||ppp_priv_area->chap)){
-		kfree(ppp_priv_area);
-		return -EINVAL;
-	}
-
-	/* If no passwords are specified */
-	if(!strlen(conf->passwd) && (ppp_priv_area->pap||ppp_priv_area->chap)){
-		kfree(ppp_priv_area);
-		return -EINVAL;
-	}
-
-	if(strlen(conf->sysname) > 31){
-		kfree(ppp_priv_area);
-		return -EINVAL;
-	}
-
-	/* If no system name is specified */
-	if(!strlen(conf->sysname) && (card->u.p.authenticator)){
-		kfree(ppp_priv_area);
-		return -EINVAL;
-	}
-
-	/* copy the data into the ppp private structure */
-	memcpy(ppp_priv_area->userid, conf->userid, strlen(conf->userid));
-	memcpy(ppp_priv_area->passwd, conf->passwd, strlen(conf->passwd));
-	memcpy(ppp_priv_area->sysname, conf->sysname, strlen(conf->sysname));
-
-	
-	ppp_priv_area->enable_IPX = conf->enable_IPX;
-	if (conf->network_number){
-		ppp_priv_area->network_number = conf->network_number;
-	}else{
-		ppp_priv_area->network_number = 0xDEADBEEF;
-	}
-
-	/* Tells us that if this interface is a
-         * gateway or not */
-	if ((ppp_priv_area->gateway = conf->gateway) == WANOPT_YES){
-		printk(KERN_INFO "%s: Interface %s is set as a gateway.\n",
-			card->devname,card->u.p.if_name);
-	}
-
-	/* prepare network device data space for registration */
- 	strcpy(dev->name,card->u.p.if_name);
-	
-	dev->init = &if_init;
-	dev->priv = ppp_priv_area;
-	dev->mtu = min_t(unsigned int, dev->mtu, card->wandev.mtu);
-
-	/* Initialize the polling work routine */
-	INIT_WORK(&ppp_priv_area->poll_work, (void*)(void*)ppp_poll, dev);
-
-	/* Initialize the polling delay timer */
-	init_timer(&ppp_priv_area->poll_delay_timer);
-	ppp_priv_area->poll_delay_timer.data = (unsigned long)dev;
-	ppp_priv_area->poll_delay_timer.function = ppp_poll_delay;
-	
-	
-	/* Since we start with dummy IP addresses we can say
-	 * that route exists */
-	printk(KERN_INFO "\n");
-
-	return 0;
-}
-
-/*============================================================================
- * Delete logical channel.
- */
-static int del_if(struct wan_device *wandev, struct net_device *dev)
-{
-	return 0;
-}
-
-static void disable_comm (sdla_t *card)
-{
-	ppp_comm_disable_shutdown(card);
-	return;
-}
-
-/****** WANPIPE-specific entry points ***************************************/
-
-/*============================================================================
- * Execute adapter interface command.
- */
-
-//FIXME: Why do we need this ????
-static int wpp_exec(struct sdla *card, void *u_cmd, void *u_data)
-{
-	ppp_mbox_t *mbox = card->mbox;
-	int len;
-
-	if (copy_from_user((void*)&mbox->cmd, u_cmd, sizeof(ppp_cmd_t)))
-		return -EFAULT;
-
-	len = mbox->cmd.length;
-
-	if (len) {
-
-		if( copy_from_user((void*)&mbox->data, u_data, len))
-			return -EFAULT;
-
-	}
-
-	/* execute command */
-	if (!sdla_exec(mbox))
-		return -EIO;
-
-	/* return result */
-	if( copy_to_user(u_cmd, (void*)&mbox->cmd, sizeof(ppp_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)
-{
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	sdla_t *card = ppp_priv_area->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;
-
-	/* Enable Mulitcasting if specified by user*/
-	if (ppp_priv_area->mc == WANOPT_YES){
-		dev->flags	|= IFF_MULTICAST;
-	}
-
-	dev->mtu		= wandev->mtu;
-	dev->hard_header_len	= PPP_HDR_LEN;	/* media header length */
-
-	/* 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 transmit buffer queue length */
-        dev->tx_queue_len = 100;
-	SET_MODULE_OWNER(dev);
-   
-	return 0;
-}
-
-/*============================================================================
- * Open network interface.
- * o 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)
-{
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	sdla_t *card = ppp_priv_area->card;
-	struct timeval tv;
-	//unsigned long smp_flags;
-
-	if (netif_running(dev))
-		return -EBUSY;
-
-	wanpipe_open(card);
-
-	netif_start_queue(dev);
-	
-	do_gettimeofday( &tv );
-	ppp_priv_area->router_start_time = tv.tv_sec;
-
-	/* We cannot configure the card here because we don't
-	 * have access to the interface IP addresses.
-         * Once the interface initilization is complete, we will be
-         * able to access the IP addresses.  Therefore,
-         * configure the ppp link in the poll routine */
-	set_bit(0,&ppp_priv_area->config_ppp);
-	ppp_priv_area->config_wait_timeout=jiffies;
-
-	/* Start the PPP configuration after 1sec delay.
-	 * This will give the interface initilization time
-	 * to finish its configuration */
-	mod_timer(&ppp_priv_area->poll_delay_timer, jiffies + HZ);
-	return 0;
-}
-
-/*============================================================================
- * 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)
-{
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	sdla_t *card = ppp_priv_area->card;
-
-	netif_stop_queue(dev);
-	wanpipe_close(card);
-
-	del_timer (&ppp_priv_area->poll_delay_timer);
-	return 0;
-}
-
-/*============================================================================
- * Build media header.
- *
- * The trick here is to put packet type (Ethertype) into 'protocol' field of
- * the socket buffer, so that we don't forget it.  If packet type is not
- * supported, set skb->protocol to 0 and discard packet later.
- *
- * Return:	media header length.
- */
-static int if_header(struct sk_buff *skb, struct net_device *dev,
-	unsigned short type, void *daddr, void *saddr, unsigned len)
-{
-	switch (type)
-	{
-		case ETH_P_IP:
-		case ETH_P_IPX:
-			skb->protocol = htons(type);
-			break;
-
-		default:
-			skb->protocol = 0;
-	}
-
-	return PPP_HDR_LEN;
-}
-
-/*============================================================================
- * 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;
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	sdla_t *card = ppp_priv_area->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)
-{
-    	ppp_private_area_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->if_send_stat.if_send_tbusy;
-	++card->wandev.stats.collisions;
-
-	printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
-	++chan->if_send_stat.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 check link state. If link is not up, then drop the packet.
- * o execute adapter send command.
- * o free socket buffer
- *
- * Return:	0	complete (socket buffer must be freed)
- *		non-0	packet may be re-transmitted (tbusy must be set)
- *
- * Notes:
- * 1. This routine is called either by the protocol stack or by the "net
- *    bottom half" (with interrupts enabled).
- * 2. Setting tbusy flag will inhibit further transmit requests from the
- *    protocol stack and can be used for flow control with protocol layer.
- */
-static int if_send (struct sk_buff *skb, struct net_device *dev)
-{
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	sdla_t *card = ppp_priv_area->card;
-	unsigned char *sendpacket;
-	unsigned long smp_flags;
-	ppp_flags_t *flags = card->flags;
-	int udp_type;
-	int err=0;
-	
-	++ppp_priv_area->if_send_stat.if_send_entry;
-
-	netif_stop_queue(dev);
-	
-	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);
-		
-		++ppp_priv_area->if_send_stat.if_send_skb_null;
-	
-		netif_wake_queue(dev);
-		return 0;
-	}
-
-	sendpacket = skb->data;
-
-	udp_type = udp_pkt_type( skb, card );
-
-
-	if (udp_type == UDP_PTPIPE_TYPE){
-		if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
-                	              ppp_priv_area)){
-	               	flags->imask |= PPP_INTR_TIMER;
-		}
-		++ppp_priv_area->if_send_stat.if_send_PIPE_request;
-		netif_start_queue(dev);
-		return 0;
-	}
-
-	/* Check for broadcast and multicast addresses 
-	 * If found, drop (deallocate) a packet and return.
-	 */
-	if(chk_bcast_mcast_addr(card, dev, skb)){
-		++card->wandev.stats.tx_dropped;
-		dev_kfree_skb_any(skb);
-		netif_start_queue(dev);
-		return 0;
-	}
-
-
- 	if(card->hw.type != SDLA_S514){
-		s508_lock(card,&smp_flags);
-	}
-
-    	if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
-
-		printk(KERN_INFO "%s: Critical in if_send: %lx\n",
-				card->wandev.name,card->wandev.critical);
-		
-		++card->wandev.stats.tx_dropped;
-		++ppp_priv_area->if_send_stat.if_send_critical_non_ISR;
-		netif_start_queue(dev);
-		goto if_send_exit_crit;
-	}
-
-	if (card->wandev.state != WAN_CONNECTED) {
-
-		++ppp_priv_area->if_send_stat.if_send_wan_disconnected;
-        	++card->wandev.stats.tx_dropped;
-		netif_start_queue(dev);
-		
-     	} else if (!skb->protocol) {
-		++ppp_priv_area->if_send_stat.if_send_protocol_error;
-        	++card->wandev.stats.tx_errors;
-		netif_start_queue(dev);
-		
-	} else {
-
-		/*If it's IPX change the network numbers to 0 if they're ours.*/
-		if( skb->protocol == htons(ETH_P_IPX) ) {
-			if(ppp_priv_area->enable_IPX) {
-				switch_net_numbers( skb->data, 
-					ppp_priv_area->network_number, 0);
-			} else {
-				++card->wandev.stats.tx_dropped;
-				netif_start_queue(dev);
-				goto if_send_exit_crit;
-			}
-		}
-
-		if (ppp_send(card, skb->data, skb->len, skb->protocol)) {
-			netif_stop_queue(dev);
-			++ppp_priv_area->if_send_stat.if_send_adptr_bfrs_full;
-			++ppp_priv_area->if_send_stat.if_send_tx_int_enabled;
-		} else {
-			++ppp_priv_area->if_send_stat.if_send_bfr_passed_to_adptr;
-			++card->wandev.stats.tx_packets;
-			card->wandev.stats.tx_bytes += skb->len;
-			netif_start_queue(dev);
-			dev->trans_start = jiffies;
-		}
-    	}
-	
-if_send_exit_crit:
-	
-	if (!(err=netif_queue_stopped(dev))){
-      		dev_kfree_skb_any(skb);
-	}else{
-		ppp_priv_area->tick_counter = jiffies;
-		flags->imask |= PPP_INTR_TXRDY;	/* unmask Tx interrupts */
-	}
-	
-	clear_bit(SEND_CRIT,&card->wandev.critical);
-	if(card->hw.type != SDLA_S514){	
-		s508_unlock(card,&smp_flags);
-	}
-
-	return err;
-}
-
-
-/*=============================================================================
- * Store a UDP management packet for later processing.
- */
-
-static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
-                                struct sk_buff *skb, struct net_device* dev,
-                                ppp_private_area_t* ppp_priv_area )
-{
-	int udp_pkt_stored = 0;
-
-	if(!ppp_priv_area->udp_pkt_lgth && (skb->len<=MAX_LGTH_UDP_MGNT_PKT)){
-        	ppp_priv_area->udp_pkt_lgth = skb->len;
-		ppp_priv_area->udp_pkt_src = udp_pkt_src;
-       		memcpy(ppp_priv_area->udp_pkt_data, skb->data, skb->len);
-		ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_UDP;
-		ppp_priv_area->protocol = skb->protocol;
-		udp_pkt_stored = 1;
-	}else{
-		if (skb->len > MAX_LGTH_UDP_MGNT_PKT){
-			printk(KERN_INFO "%s: PIPEMON UDP request too long : %i\n",
-				card->devname, skb->len);
-		}else{
-			printk(KERN_INFO "%s: PIPEMON UPD request already pending\n",
-				card->devname);
-		}
-		ppp_priv_area->udp_pkt_lgth = 0;
-	}
-
-	if(udp_pkt_src == UDP_PKT_FRM_STACK){
-		dev_kfree_skb_any(skb);
-	}else{
-                dev_kfree_skb_any(skb);
-	}
-
-	return(udp_pkt_stored);
-}
-
-
-
-/*============================================================================
- * 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;
-	ppp_udp_pkt_t *p_udp_pkt = (ppp_udp_pkt_t *)data;
- 
-	/* Set length of packet */
-	len = sizeof(ip_pkt_t)+ 
-	      sizeof(udp_pkt_t)+
-	      sizeof(wp_mgmt_t)+
-	      sizeof(cblock_t)+
-	      mbox_len;
-
-	/* fill in UDP reply */
-  	p_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)+
-		     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);
-	p_udp_pkt->udp_pkt.udp_length = temp;		
-
- 
-	/* swap UDP ports */
-	temp = p_udp_pkt->udp_pkt.udp_src_port;
-	p_udp_pkt->udp_pkt.udp_src_port = 
-			p_udp_pkt->udp_pkt.udp_dst_port; 
-	p_udp_pkt->udp_pkt.udp_dst_port = temp;
-
-
-	/* add UDP pseudo header */
-	temp = 0x1100;
-	*((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound)) = temp;
-	temp = (udp_length<<8)|(udp_length>>8);
-	*((unsigned short *)(p_udp_pkt->data+mbox_len+even_bound+2)) = temp;
- 
-	/* calculate UDP checksum */
-	p_udp_pkt->udp_pkt.udp_checksum = 0;
-	p_udp_pkt->udp_pkt.udp_checksum = 
-		calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
-
-	/* fill in IP length */
-	ip_length = udp_length + sizeof(ip_pkt_t);
-	temp = (ip_length<<8)|(ip_length>>8);
-  	p_udp_pkt->ip_pkt.total_length = temp;
- 
-	/* swap IP addresses */
-	ip_temp = p_udp_pkt->ip_pkt.ip_src_address;
-	p_udp_pkt->ip_pkt.ip_src_address = p_udp_pkt->ip_pkt.ip_dst_address;
-	p_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
-
-	/* fill in IP checksum */
-	p_udp_pkt->ip_pkt.hdr_checksum = 0;
-	p_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;	
-}
-
-/*
-   If incoming is 0 (outgoing)- if the net numbers is ours make it 0
-   if incoming is 1 - if the net number is 0 make it ours 
-
-*/
-static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming)
-{
-	unsigned long pnetwork_number;
-
-	pnetwork_number = (unsigned long)((sendpacket[6] << 24) + 
-			  (sendpacket[7] << 16) + (sendpacket[8] << 8) + 
-			  sendpacket[9]);
-
-	if (!incoming) {
-		//If the destination network number is ours, make it 0
-		if( pnetwork_number == network_number) {
-			sendpacket[6] = sendpacket[7] = sendpacket[8] = 
-					 sendpacket[9] = 0x00;
-		}
-	} else {
-		//If the incoming network is 0, make it ours
-		if( pnetwork_number == 0) {
-			sendpacket[6] = (unsigned char)(network_number >> 24);
-			sendpacket[7] = (unsigned char)((network_number & 
-					 0x00FF0000) >> 16);
-			sendpacket[8] = (unsigned char)((network_number & 
-					 0x0000FF00) >> 8);
-			sendpacket[9] = (unsigned char)(network_number & 
-					 0x000000FF);
-		}
-	}
-
-
-	pnetwork_number = (unsigned long)((sendpacket[18] << 24) + 
-			  (sendpacket[19] << 16) + (sendpacket[20] << 8) + 
-			  sendpacket[21]);
-
-	if( !incoming ) {
-		//If the source network is ours, make it 0
-		if( pnetwork_number == network_number) {
-			sendpacket[18] = sendpacket[19] = sendpacket[20] = 
-					 sendpacket[21] = 0x00;
-		}
-	} else {
-		//If the source network is 0, make it ours
-		if( pnetwork_number == 0 ) {
-			sendpacket[18] = (unsigned char)(network_number >> 24);
-			sendpacket[19] = (unsigned char)((network_number & 
-					 0x00FF0000) >> 16);
-			sendpacket[20] = (unsigned char)((network_number & 
-					 0x0000FF00) >> 8);
-			sendpacket[21] = (unsigned char)(network_number & 
-					 0x000000FF);
-		}
-	}
-} /* switch_net_numbers */
-
-/*============================================================================
- * Get ethernet-style interface statistics.
- * Return a pointer to struct net_device_stats.
- */
-static struct net_device_stats *if_stats(struct net_device *dev)
-{
-
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	sdla_t* card;
-	
-	if( ppp_priv_area == NULL )
-		return NULL;
-
-	card = ppp_priv_area->card;
-	return &card->wandev.stats;
-}
-
-/****** PPP Firmware Interface Functions ************************************/
-
-/*============================================================================
- * Read firmware code version.
- *	Put code version as ASCII string in str. 
- */
-static int ppp_read_version(sdla_t *card, char *str)
-{
-	ppp_mbox_t *mb = card->mbox;
-	int err;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	mb->cmd.command = PPP_READ_CODE_VERSION;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-
-	if (err != CMD_OK)
- 
-		ppp_error(card, err, mb);
-
-	else if (str) {
-
-		int len = mb->cmd.length;
-
-		memcpy(str, mb->data, len);
-		str[len] = '\0';
-
-	}
-
-	return err;
-}
-/*===========================================================================
- * Set Out-Bound Authentication.
-*/
-static int ppp_set_outbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area)
-{
-	ppp_mbox_t *mb = card->mbox;
-	int err;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	memset(&mb->data, 0, (strlen(ppp_priv_area->userid) + 
-					strlen(ppp_priv_area->passwd) + 2 ) );
-	memcpy(mb->data, ppp_priv_area->userid, strlen(ppp_priv_area->userid));
-	memcpy((mb->data + strlen(ppp_priv_area->userid) + 1), 
-		ppp_priv_area->passwd, strlen(ppp_priv_area->passwd));	
-	
-	mb->cmd.length  = strlen(ppp_priv_area->userid) + 
-					strlen(ppp_priv_area->passwd) + 2 ;
-	
-	mb->cmd.command = PPP_SET_OUTBOUND_AUTH;
-
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-
-	if (err != CMD_OK)
-		ppp_error(card, err, mb);
-
-	return err;
-}
-
-/*===========================================================================
- * Set In-Bound Authentication.
-*/
-static int ppp_set_inbnd_auth (sdla_t *card, ppp_private_area_t *ppp_priv_area)
-{
-	ppp_mbox_t *mb = card->mbox;
-	int err, i;
-	char* user_tokens[32];
-	char* pass_tokens[32];
-	int userids, passwds;
-	int add_ptr;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	memset(&mb->data, 0, 1008);
-	memcpy(mb->data, ppp_priv_area->sysname, 
-						strlen(ppp_priv_area->sysname));
-	
-	/* Parse the userid string and the password string and build a string
-	   to copy it to the data area of the command structure.   The string
-	   will look like "SYS_NAME<NULL>USER1<NULL>PASS1<NULL>USER2<NULL>PASS2
-	   ....<NULL> " 
-	 */
-	userids = tokenize( ppp_priv_area->userid, user_tokens);
-	passwds = tokenize( ppp_priv_area->passwd, pass_tokens);
-	
-	if (userids != passwds){
-		printk(KERN_INFO "%s: Number of passwords does not equal the number of user ids\n", card->devname);
-		return 1;	
-	}
-
-	add_ptr = strlen(ppp_priv_area->sysname) + 1;
-	for (i=0; i<userids; i++){
-		memcpy((mb->data + add_ptr), user_tokens[i], 
-							strlen(user_tokens[i]));
-		memcpy((mb->data + add_ptr + strlen(user_tokens[i]) + 1), 
-					pass_tokens[i], strlen(pass_tokens[i]));
-		add_ptr = add_ptr + strlen(user_tokens[i]) + 1 + 
-						strlen(pass_tokens[i]) + 1;
-	}
-
-	mb->cmd.length  = add_ptr + 1;
-	mb->cmd.command = PPP_SET_INBOUND_AUTH;
-
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-
-	if (err != CMD_OK)
-		ppp_error(card, err, mb);
-
-	return err;
-}
-
-
-/*============================================================================
- * Tokenize string.
- *      Parse a string of the following syntax:
- *              <arg1>,<arg2>,...
- *      and fill array of tokens with pointers to string elements.
- *
- */
-static int tokenize (char *str, char **tokens)
-{
-        int cnt = 0;
-
-        tokens[0] = strsep(&str, "/");
-        while (tokens[cnt] && (cnt < 32 - 1))
-        {
-                tokens[cnt] = strstrip(tokens[cnt], " \t");
-                tokens[++cnt] = strsep(&str, "/");
-        }
-	return cnt;
-}
-
-/*============================================================================
- * Strip leading and trailing spaces off the string str.
- */
-static char* strstrip (char *str, char* s)
-{
-        char *eos = str + strlen(str);          /* -> end of string */
-
-        while (*str && strchr(s, *str))
-                ++str                           /* strip leading spaces */
-        ;
-        while ((eos > str) && strchr(s, *(eos - 1)))
-                --eos                           /* strip trailing spaces */
-        ;
-        *eos = '\0';
-        return str;
-}
-/*============================================================================
- * Configure PPP firmware.
- */
-static int ppp_configure(sdla_t *card, void *data)
-{
-	ppp_mbox_t *mb = card->mbox;
-	int data_len = sizeof(ppp508_conf_t); 
-	int err;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	memcpy(mb->data, data, data_len);
-	mb->cmd.length  = data_len;
-	mb->cmd.command = PPP_SET_CONFIG;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-
-	if (err != CMD_OK) 
-		ppp_error(card, err, mb);
-	
-	return err;
-}
-
-/*============================================================================
- * Set interrupt mode.
- */
-static int ppp_set_intr_mode(sdla_t *card, unsigned char mode)
-{
-	ppp_mbox_t *mb = card->mbox;
-        ppp_intr_info_t *ppp_intr_data = (ppp_intr_info_t *) &mb->data[0];
-	int err;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	ppp_intr_data->i_enable = mode;
-
-	ppp_intr_data->irq = card->hw.irq;
-	mb->cmd.length = 2;
-
-       /* If timer has been enabled, set the timer delay to 1sec */
-       if (mode & 0x80){
-       		ppp_intr_data->timer_len = 250; //5;//100; //250;
-                mb->cmd.length = 4;
-        }
-	
-	mb->cmd.command = PPP_SET_INTR_FLAGS;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-	
-	if (err != CMD_OK) 
-		ppp_error(card, err, mb);
- 		
-
-	return err;
-}
-
-/*============================================================================
- * Enable communications.
- */
-static int ppp_comm_enable(sdla_t *card)
-{
-	ppp_mbox_t *mb = card->mbox;
-	int err;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	mb->cmd.command = PPP_COMM_ENABLE;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-	
-	if (err != CMD_OK) 
-		ppp_error(card, err, mb);
-	else	
-		card->u.p.comm_enabled = 1;	
-
-	return err;
-}
-
-/*============================================================================
- * Disable communications.
- */
-static int ppp_comm_disable(sdla_t *card)
-{
-	ppp_mbox_t *mb = card->mbox;
-	int err;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	mb->cmd.command = PPP_COMM_DISABLE;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-	if (err != CMD_OK) 
-		ppp_error(card, err, mb);
-	else
-		card->u.p.comm_enabled = 0;
-
-	return err;
-}
-
-static int ppp_comm_disable_shutdown(sdla_t *card)
-{
-	ppp_mbox_t *mb = card->mbox;
-	ppp_intr_info_t *ppp_intr_data;
-	int err;
-
-	if (!mb){
-		return 1;
-	}
-	
-	ppp_intr_data = (ppp_intr_info_t *) &mb->data[0];
-	
-	/* Disable all interrupts */
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	ppp_intr_data->i_enable = 0;
-
-	ppp_intr_data->irq = card->hw.irq;
-	mb->cmd.length = 2;
-
-	mb->cmd.command = PPP_SET_INTR_FLAGS;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-
-	/* Disable communicatinons */
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	mb->cmd.command = PPP_COMM_DISABLE;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-
-	card->u.p.comm_enabled = 0;
-
-	return 0;
-}
-
-
-
-/*============================================================================
- * Get communications error statistics.
- */
-static int ppp_get_err_stats(sdla_t *card)
-{
-	ppp_mbox_t *mb = card->mbox;
-	int err;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	mb->cmd.command = PPP_READ_ERROR_STATS;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-	
-	if (err == CMD_OK) {
-		
-		ppp_err_stats_t* stats = (void*)mb->data;
-		card->wandev.stats.rx_over_errors    = stats->rx_overrun;
-		card->wandev.stats.rx_crc_errors     = stats->rx_bad_crc;
-		card->wandev.stats.rx_missed_errors  = stats->rx_abort;
-		card->wandev.stats.rx_length_errors  = stats->rx_lost;
-		card->wandev.stats.tx_aborted_errors = stats->tx_abort;
-	
-	} else 
-		ppp_error(card, err, mb);
-	
-	return err;
-}
-
-/*============================================================================
- * Send packet.
- *	Return:	0 - o.k.
- *		1 - no transmit buffers available
- */
-static int ppp_send (sdla_t *card, void *data, unsigned len, unsigned proto)
-{
-	ppp_buf_ctl_t *txbuf = card->u.p.txbuf;
-
-	if (txbuf->flag)
-                return 1;
-	
-	sdla_poke(&card->hw, txbuf->buf.ptr, data, len);
-
-	txbuf->length = len;		/* frame length */
-	
-	if (proto == htons(ETH_P_IPX))
-		txbuf->proto = 0x01;	/* protocol ID */
-	else
-		txbuf->proto = 0x00;	/* protocol ID */
-	
-	txbuf->flag = 1;		/* start transmission */
-
-	/* Update transmit buffer control fields */
-	card->u.p.txbuf = ++txbuf;
-
-	if ((void*)txbuf > card->u.p.txbuf_last)
-		card->u.p.txbuf = card->u.p.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 ppp_error(sdla_t *card, int err, ppp_mbox_t *mb)
-{
-	unsigned cmd = mb->cmd.command;
-
-	switch (err) {
-
-		case CMD_TIMEOUT:
-			printk(KERN_ERR "%s: command 0x%02X timed out!\n",
-				card->devname, cmd);
-			break;
-
-		default:
-			printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n"
-				, card->devname, cmd, err);
-	}
-
-	return 0;
-}
-
-/****** Interrupt Handlers **************************************************/
-
-/*============================================================================
- * PPP interrupt service routine.
- */
-static void wpp_isr (sdla_t *card)
-{
-	ppp_flags_t *flags = card->flags;
-	char *ptr = &flags->iflag;
-	struct net_device *dev = card->wandev.dev;
-	int i;
-
-	card->in_isr = 1;
-	++card->statistics.isr_entry;
-
-	if (!dev && flags->iflag != PPP_INTR_CMD){
-		card->in_isr = 0;
-		flags->iflag = 0;
-		return;
-	}
-	
-	if (test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
-		card->in_isr = 0;
-		flags->iflag = 0;
-		return;
-	}
-	
-	
-	if(card->hw.type != SDLA_S514){
-		if (test_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
-			++card->statistics.isr_already_critical;
-			printk (KERN_INFO "%s: Critical while in ISR!\n",
-					card->devname);
-			card->in_isr = 0;
-			flags->iflag = 0;
-			return;
-		}
-	}
-
-	switch (flags->iflag) {
-
-		case PPP_INTR_RXRDY:	/* receive interrupt  0x01  (bit 0)*/
-			++card->statistics.isr_rx;
-			rx_intr(card);
-			break;
-
-		case PPP_INTR_TXRDY:	/* transmit interrupt  0x02 (bit 1)*/
-			++card->statistics.isr_tx;
-			flags->imask &= ~PPP_INTR_TXRDY;
-			netif_wake_queue(dev);
-			break;
-
-		case PPP_INTR_CMD:      /* interface command completed */
-			++Intr_test_counter;
-			++card->statistics.isr_intr_test;
-			break;
-
-		case PPP_INTR_MODEM:    /* modem status change (DCD, CTS) 0x04 (bit 2)*/
-		case PPP_INTR_DISC:  	/* Data link disconnected 0x10  (bit 4)*/	
-		case PPP_INTR_OPEN:   	/* Data link open 0x20  (bit 5)*/
-		case PPP_INTR_DROP_DTR:	/* DTR drop timeout expired  0x40 bit 6 */
-			event_intr(card);
-			break;
-	
-		case PPP_INTR_TIMER:
-			timer_intr(card);
-			break;	 
-
-		default:	/* unexpected interrupt */
-			++card->statistics.isr_spurious;
-			printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", 
-				card->devname, flags->iflag);
-			printk(KERN_INFO "%s: ID Bytes = ",card->devname);
-	 		for(i = 0; i < 8; i ++)
-				printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
-			printk(KERN_INFO "\n");	
-	}
-	
-	card->in_isr = 0;
-	flags->iflag = 0;
-	return;
-}
-
-/*============================================================================
- * Receive interrupt handler.
- */
-static void rx_intr(sdla_t *card)
-{
-	ppp_buf_ctl_t *rxbuf = card->rxmb;
-	struct net_device *dev = card->wandev.dev;
-	ppp_private_area_t *ppp_priv_area;
-	struct sk_buff *skb;
-	unsigned len;
-	void *buf;
-	int i;
-        ppp_flags_t *flags = card->flags;
-        char *ptr = &flags->iflag;
-	int udp_type;
-	
-
-	if (rxbuf->flag != 0x01) {
-
-		printk(KERN_INFO 
-			"%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", 
-			card->devname, (unsigned)rxbuf, rxbuf->flag);
-	
-		printk(KERN_INFO "%s: ID Bytes = ",card->devname);
-	 	
-		for(i = 0; i < 8; i ++)
-			printk(KERN_INFO "0x%02X ", *(ptr + 0x28 + i));
-		printk(KERN_INFO "\n");	
-		
-		++card->statistics.rx_intr_corrupt_rx_bfr;
-
-
-		/* Bug Fix: Mar 6 2000
-                 * If we get a corrupted mailbox, it means that driver 
-                 * is out of sync with the firmware. There is no recovery.
-                 * If we don't turn off all interrupts for this card
-                 * the machine will crash. 
-                 */
-		printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
-		printk(KERN_INFO "Please contact Sangoma Technologies !\n");
-		ppp_set_intr_mode(card,0);
-		return;
-	}
-      
-	if (dev && netif_running(dev) && dev->priv){
-	
-		len  = rxbuf->length;
-		ppp_priv_area = dev->priv;
-
-		/* Allocate socket buffer */
-		skb = dev_alloc_skb(len);
-
-		if (skb != NULL) {
-		
-			/* Copy data to the socket buffer */
-			unsigned addr = rxbuf->buf.ptr;
-
-			if ((addr + len) > card->u.p.rx_top + 1) {
-			
-				unsigned tmp = card->u.p.rx_top - addr + 1;
-				buf = skb_put(skb, tmp);
-				sdla_peek(&card->hw, addr, buf, tmp);
-				addr = card->u.p.rx_base;
-				len -= tmp;
-			}
-			buf = skb_put(skb, len);
-			sdla_peek(&card->hw, addr, buf, len);
-
-			/* Decapsulate packet */
-        		switch (rxbuf->proto) {
-	
-				case 0x00:
-					skb->protocol = htons(ETH_P_IP);
-					break;
-
-				case 0x01:
-					skb->protocol = htons(ETH_P_IPX);
-					break;
-			}
-
-			udp_type = udp_pkt_type( skb, card );
-
-			if (udp_type == UDP_PTPIPE_TYPE){
-
-				/* Handle a UDP Request in Timer Interrupt */
-				if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK, card, skb, dev,
-                	              			ppp_priv_area)){
-	               			flags->imask |= PPP_INTR_TIMER;
-				}
-				++ppp_priv_area->rx_intr_stat.rx_intr_PIPE_request;
-
-
-			} else if (handle_IPXWAN(skb->data,card->devname, 
-						 ppp_priv_area->enable_IPX, 
-						 ppp_priv_area->network_number, 
-						 skb->protocol)) {
-			
-				/* Handle an IPXWAN packet */
-				if( ppp_priv_area->enable_IPX) {
-					
-					/* Make sure we are not already sending */
-					if (!test_bit(SEND_CRIT, &card->wandev.critical)){
-					 	ppp_send(card, skb->data, skb->len, htons(ETH_P_IPX));
-					}
-					dev_kfree_skb_any(skb);
-
-				} else {
-					++card->wandev.stats.rx_dropped;
-				}
-			} else {
-				/* Pass data up the protocol stack */
-	    			skb->dev = dev;
-				skb->mac.raw  = skb->data;
-
-			    	++card->wandev.stats.rx_packets;
-				card->wandev.stats.rx_bytes += skb->len;
-		    		++ppp_priv_area->rx_intr_stat.rx_intr_bfr_passed_to_stack;	
-				netif_rx(skb);
-				dev->last_rx = jiffies;
-			}
-
-		} else {
-	
-			if (net_ratelimit()){
-				printk(KERN_INFO "%s: no socket buffers available!\n",
-					card->devname);
-			}
-			++card->wandev.stats.rx_dropped;
-			++ppp_priv_area->rx_intr_stat.rx_intr_no_socket;
-		}
-
-	} else {
-		++card->statistics.rx_intr_dev_not_started;
-	}
-
-	/* Release buffer element and calculate a pointer to the next one */
-	rxbuf->flag = 0x00;
-	card->rxmb = ++rxbuf;
-	if ((void*)rxbuf > card->u.p.rxbuf_last)
-		card->rxmb = card->u.p.rxbuf_base;
-}
-
-
-void event_intr (sdla_t *card)
-{
-
- 	struct net_device* dev = card->wandev.dev;
-        ppp_private_area_t* ppp_priv_area = dev->priv;
-	volatile ppp_flags_t *flags = card->flags;
-
-	switch (flags->iflag){
-
-		case PPP_INTR_MODEM:    /* modem status change (DCD, CTS) 0x04  (bit 2)*/
-
-			if (net_ratelimit()){
-				printk (KERN_INFO "%s: Modem status: DCD=%s CTS=%s\n",
-					card->devname, DCD(flags->mstatus), CTS(flags->mstatus));
-			}
-			break;
-
-		case PPP_INTR_DISC:  	/* Data link disconnected 0x10  (bit 4)*/	
-
-			NEX_PRINTK (KERN_INFO "Data link disconnected intr Cause %X\n",
-					       flags->disc_cause);
-
-			if (flags->disc_cause &
-				(PPP_LOCAL_TERMINATION | PPP_DCD_CTS_DROP |
-				PPP_REMOTE_TERMINATION)) {
-
-				if (card->u.p.ip_mode == WANOPT_PPP_PEER) { 
-					set_bit(0,&Read_connection_info);
-				}
-				wanpipe_set_state(card, WAN_DISCONNECTED);
-
-				show_disc_cause(card, flags->disc_cause);
-				ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT;
-				flags->imask |= PPP_INTR_TIMER;
-				trigger_ppp_poll(dev);
-			}
-			break;
-
-		case PPP_INTR_OPEN:   	/* Data link open 0x20  (bit 5)*/
-
-			NEX_PRINTK (KERN_INFO "%s: PPP Link Open, LCP=%s IP=%s\n",
-					card->devname,LCP(flags->lcp_state),
-					IP(flags->ip_state));
-
-			if (flags->lcp_state == 0x09 && 
-                           (flags->ip_state == 0x09 || flags->ipx_state == 0x09)){
-
-                                /* Initialize the polling timer and set the state
-                                 * to WAN_CONNNECTED */
-
-
-				/* BUG FIX: When the protocol restarts, during heavy 
-                                 * traffic, board tx buffers and driver tx buffers
-                                 * can go out of sync.  This checks the condition
-                                 * and if the tx buffers are out of sync, the 
-                                 * protocols are restarted. 
-                                 * I don't know why the board tx buffer is out
-                                 * of sync. It could be that a packets is tx
-                                 * while the link is down, but that is not 
-                                 * possible. The other possiblility is that the
-                                 * firmware doesn't reinitialize properly.
-                                 * FIXME: A better fix should be found.
-                                 */ 
-				if (detect_and_fix_tx_bug(card)){
-
-					ppp_comm_disable(card);
-
-					wanpipe_set_state(card, WAN_DISCONNECTED);
-
-					ppp_priv_area->timer_int_enabled |= 
-						TMR_INT_ENABLED_PPP_EVENT;
-					flags->imask |= PPP_INTR_TIMER;
-					break;	
-				}
-
-				card->state_tick = jiffies;
-				wanpipe_set_state(card, WAN_CONNECTED);
-
-				NEX_PRINTK(KERN_INFO "CON: L Tx: %lx  B Tx: %lx || L Rx %lx B Rx %lx\n",
-					(unsigned long)card->u.p.txbuf, *card->u.p.txbuf_next,
-					(unsigned long)card->rxmb, *card->u.p.rxbuf_next);
-
-				/* Tell timer interrupt that PPP event occurred */
-				ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT;
-				flags->imask |= PPP_INTR_TIMER;
-
-				/* If we are in PEER mode, we must first obtain the
-				 * IP information and then go into the poll routine */
-				if (card->u.p.ip_mode != WANOPT_PPP_PEER){	
-					trigger_ppp_poll(dev);
-				}
-			}
-                   	break;
-
-		case PPP_INTR_DROP_DTR:		/* DTR drop timeout expired  0x40 bit 6 */
-
-			NEX_PRINTK(KERN_INFO "DTR Drop Timeout Interrrupt \n"); 
-
-			if (card->u.p.ip_mode == WANOPT_PPP_PEER) { 
-				set_bit(0,&Read_connection_info);
-			}
-		
-			wanpipe_set_state(card, WAN_DISCONNECTED);
-
-			show_disc_cause(card, flags->disc_cause);
-			ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_PPP_EVENT;
-			flags->imask |= PPP_INTR_TIMER;
-			trigger_ppp_poll(dev);
-			break;
-		
-		default:
-			printk(KERN_INFO "%s: Error, Invalid PPP Event\n",card->devname);
-	}
-}
-
-
-
-/* TIMER INTERRUPT */
-
-void timer_intr (sdla_t *card)
-{
-
-        struct net_device* dev = card->wandev.dev;
-        ppp_private_area_t* ppp_priv_area = dev->priv;
-	ppp_flags_t *flags = card->flags;
-
-
-	if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG){
-		if (!config_ppp(card)){
-			ppp_priv_area->timer_int_enabled &= 
-					~TMR_INT_ENABLED_CONFIG;	
-		}
-	}
-
-	/* Update statistics */
-	if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE){
-		ppp_get_err_stats(card);
-                if(!(--ppp_priv_area->update_comms_stats)){
-			ppp_priv_area->timer_int_enabled &= 
-				~TMR_INT_ENABLED_UPDATE;
-		}
-	}
-
-	/* PPIPEMON UDP request */
-
-	if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP){
-		process_udp_mgmt_pkt(card,dev, ppp_priv_area);
-		ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
-	}
-
-	/* PPP Event */
-	if (ppp_priv_area->timer_int_enabled & TMR_INT_ENABLED_PPP_EVENT){
-
-		if (card->wandev.state == WAN_DISCONNECTED){
-			retrigger_comm(card);
-		}
-
-		/* If the state is CONNECTING, it means that communicatins were
-	 	 * enabled. When the remote side enables its comminication we
-	 	 * should get an interrupt PPP_INTR_OPEN, thus turn off polling 
-		 */
-
-		else if (card->wandev.state == WAN_CONNECTING){
-			/* Turn off the timer interrupt */
-			ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT;
-		}
-
-		/* If state is connected and we are in PEER mode 
-	 	 * poll for an IP address which will be provided by remote end.
-	 	 */
-		else if ((card->wandev.state == WAN_CONNECTED && 
-		  	  card->u.p.ip_mode == WANOPT_PPP_PEER) && 
-		  	  test_bit(0,&Read_connection_info)){
-
-			card->state_tick = jiffies;
-			if (read_connection_info (card)){
-				printk(KERN_INFO "%s: Failed to read PEER IP Addresses\n",
-					card->devname);
-			}else{
-				clear_bit(0,&Read_connection_info);
-				set_bit(1,&Read_connection_info);
-				trigger_ppp_poll(dev);
-			}
-		}else{
-			//FIXME Put the comment back int
-			ppp_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_PPP_EVENT;
-		}
-
-	}/* End of PPP_EVENT */
-
-
-	/* Only disable the timer interrupt if there are no udp, statistic */
-	/* updates or events pending */
-        if(!ppp_priv_area->timer_int_enabled) {
-                flags->imask &= ~PPP_INTR_TIMER;
-        }
-}
-
-
-static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto)
-{
-	int i;
-
-	if( proto == htons(ETH_P_IPX) ) {
-		//It's an IPX packet
-		if(!enable_IPX) {
-			//Return 1 so we don't pass it up the stack.
-			return 1;
-		}
-	} else {
-		//It's not IPX so pass it up the stack.
-		return 0;
-	}
-
-	if( sendpacket[16] == 0x90 &&
-	    sendpacket[17] == 0x04)
-	{
-		//It's IPXWAN
-
-		if( sendpacket[2] == 0x02 &&
-		    sendpacket[34] == 0x00)
-		{
-			//It's a timer request packet
-			printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname);
-
-			//Go through the routing options and answer no to every
-			//option except Unnumbered RIP/SAP
-			for(i = 41; sendpacket[i] == 0x00; i += 5)
-			{
-				//0x02 is the option for Unnumbered RIP/SAP
-				if( sendpacket[i + 4] != 0x02)
-				{
-					sendpacket[i + 1] = 0;
-				}
-			}
-
-			//Skip over the extended Node ID option
-			if( sendpacket[i] == 0x04 )
-			{
-				i += 8;
-			}
-
-			//We also want to turn off all header compression opt.
-			for(; sendpacket[i] == 0x80 ;)
-			{
-				sendpacket[i + 1] = 0;
-				i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4;
-			}
-
-			//Set the packet type to timer response
-			sendpacket[34] = 0x01;
-
-			printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname);
-		}
-		else if( sendpacket[34] == 0x02 )
-		{
-			//This is an information request packet
-			printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname);
-
-			//Set the packet type to information response
-			sendpacket[34] = 0x03;
-
-			//Set the router name
-			sendpacket[51] = 'P';
-			sendpacket[52] = 'T';
-			sendpacket[53] = 'P';
-			sendpacket[54] = 'I';
-			sendpacket[55] = 'P';
-			sendpacket[56] = 'E';
-			sendpacket[57] = '-';
-			sendpacket[58] = CVHexToAscii(network_number >> 28);
-			sendpacket[59] = CVHexToAscii((network_number & 0x0F000000)>> 24);
-			sendpacket[60] = CVHexToAscii((network_number & 0x00F00000)>> 20);
-			sendpacket[61] = CVHexToAscii((network_number & 0x000F0000)>> 16);
-			sendpacket[62] = CVHexToAscii((network_number & 0x0000F000)>> 12);
-			sendpacket[63] = CVHexToAscii((network_number & 0x00000F00)>> 8);
-			sendpacket[64] = CVHexToAscii((network_number & 0x000000F0)>> 4);
-			sendpacket[65] = CVHexToAscii(network_number & 0x0000000F);
-			for(i = 66; i < 99; i+= 1)
-			{
-				sendpacket[i] = 0;
-			}
-
-			printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname);
-		}
-		else
-		{
-			printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname);
-			return 0;
-		}
-
-		//Set the WNodeID to our network address
-		sendpacket[35] = (unsigned char)(network_number >> 24);
-		sendpacket[36] = (unsigned char)((network_number & 0x00FF0000) >> 16);
-		sendpacket[37] = (unsigned char)((network_number & 0x0000FF00) >> 8);
-		sendpacket[38] = (unsigned char)(network_number & 0x000000FF);
-
-		return 1;
-	} else {
-		//If we get here it's an IPX-data packet, so it'll get passed up the stack.
-
-		//switch the network numbers
-		switch_net_numbers(sendpacket, network_number, 1);	
-		return 0;
-	}
-}
-
-/****** Background Polling Routines  ****************************************/
-
-/* All polling functions are invoked by the TIMER interrupt in the wpp_isr 
- * routine.  
- */
-
-/*============================================================================
- * Monitor active link phase.
- */
-static void process_route (sdla_t *card)
-{
-	ppp_flags_t *flags = card->flags;
-	struct net_device *dev = card->wandev.dev;
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	
-	if ((card->u.p.ip_mode == WANOPT_PPP_PEER) &&
-	    (flags->ip_state == 0x09)){ 
-
-		/* We get ip_local from the firmware in PEER mode.
-	         * Therefore, if ip_local is 0, we failed to obtain
-         	 * the remote IP address. */
-		if (ppp_priv_area->ip_local == 0) 
-			return;
-		
-		printk(KERN_INFO "%s: IPCP State Opened.\n", card->devname);
-		if (read_info( card )) {
-   			printk(KERN_INFO 
-				"%s: An error occurred in IP assignment.\n", 
-				card->devname);
-		} else {
-			struct in_device *in_dev = dev->ip_ptr;
-			if (in_dev != NULL ) {
-				struct in_ifaddr *ifa = in_dev->ifa_list;
-
-				printk(KERN_INFO "%s: Assigned Lcl. Addr: %u.%u.%u.%u\n", 
-					card->devname, NIPQUAD(ifa->ifa_local));
-				printk(KERN_INFO "%s: Assigned Rmt. Addr: %u.%u.%u.%u\n", 
-						card->devname, NIPQUAD(ifa->ifa_address));
-			}else{
-				printk(KERN_INFO 
-				"%s: Error: Failed to add a route for PPP interface %s\n",
-					card->devname,dev->name);	
-			}
-		}
-	}
-}
-
-/*============================================================================
- * Monitor physical link disconnected phase.
- *  o if interface is up and the hold-down timeout has expired, then retry
- *    connection.
- */
-static void retrigger_comm(sdla_t *card)
-{
-	struct net_device *dev = card->wandev.dev;
-
-	if (dev && ((jiffies - card->state_tick) > HOLD_DOWN_TIME)) {
-
-		wanpipe_set_state(card, WAN_CONNECTING);
-
-		if(ppp_comm_enable(card) == CMD_OK){
-			init_ppp_tx_rx_buff( card );
-		}	         
-	}
-}
-
-/****** Miscellaneous Functions *********************************************/
-
-/*============================================================================
- * Configure S508 adapter.
- */
-static int config508(struct net_device *dev, sdla_t *card)
-{
-	ppp508_conf_t cfg;
-	struct in_device *in_dev = dev->ip_ptr;
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-
-	/* Prepare PPP configuration structure */
-	memset(&cfg, 0, sizeof(ppp508_conf_t));
-
-	if (card->wandev.clocking)
-		cfg.line_speed = card->wandev.bps;
-
-	if (card->wandev.interface == WANOPT_RS232)
-		cfg.conf_flags |= INTERFACE_LEVEL_RS232;
-
-
-        cfg.conf_flags 	|= DONT_TERMINATE_LNK_MAX_CONFIG; /*send Configure-Request packets forever*/
-	cfg.txbuf_percent	= PERCENT_TX_BUFF;	/* % of Tx bufs */
-	cfg.mtu_local		= card->wandev.mtu;
-	cfg.mtu_remote		= card->wandev.mtu;                  /*    Default   */
-	cfg.restart_tmr		= TIME_BETWEEN_CONF_REQ;  	     /*    30 = 3sec */
-	cfg.auth_rsrt_tmr	= TIME_BETWEEN_PAP_CHAP_REQ;         /*    30 = 3sec */
-	cfg.auth_wait_tmr	= WAIT_PAP_CHAP_WITHOUT_REPLY;       /*   300 = 30s  */
-	cfg.mdm_fail_tmr	= WAIT_AFTER_DCD_CTS_LOW;            /*     5 = 0.5s */
-	cfg.dtr_drop_tmr	= TIME_DCD_CTS_LOW_AFTER_LNK_DOWN;   /*    10 = 1s   */
-	cfg.connect_tmout	= WAIT_DCD_HIGH_AFTER_ENABLE_COMM;   /*   900 = 90s  */
-	cfg.conf_retry		= MAX_CONF_REQ_WITHOUT_REPLY;        /*    10 = 1s   */
-	cfg.term_retry		= MAX_TERM_REQ_WITHOUT_REPLY;	     /*     2 times  */
-	cfg.fail_retry		= NUM_CONF_NAK_WITHOUT_REPLY;        /*     5 times  */
-	cfg.auth_retry		= NUM_AUTH_REQ_WITHOUT_REPLY;        /*     10 times */   
-
-
-	if( !card->u.p.authenticator ) {
-		printk(KERN_INFO "%s: Device is not configured as an authenticator\n", 
-				card->devname);
-		cfg.auth_options = NO_AUTHENTICATION;
-	}else{
-		printk(KERN_INFO "%s: Device is configured as an authenticator\n", 
-				card->devname);
-		cfg.auth_options = INBOUND_AUTH;
-	}
-
-	if( ppp_priv_area->pap == WANOPT_YES){
-		cfg.auth_options |=PAP_AUTH;
-		printk(KERN_INFO "%s: Pap enabled\n", card->devname);
-	}
-	if( ppp_priv_area->chap == WANOPT_YES){
-		cfg.auth_options |= CHAP_AUTH;
-		printk(KERN_INFO "%s: Chap enabled\n", card->devname);
-	}
-
-
-	if (ppp_priv_area->enable_IPX == WANOPT_YES){
-		printk(KERN_INFO "%s: Enabling IPX Protocol\n",card->devname);
-		cfg.ipx_options		= ENABLE_IPX | ROUTING_PROT_DEFAULT;
-	}else{
-		cfg.ipx_options 	= DISABLE_IPX;
-	}
-
-	switch (card->u.p.ip_mode) {
-	
-		case WANOPT_PPP_STATIC:
-
-			printk(KERN_INFO "%s: PPP IP Mode: STATIC\n",card->devname);
-			cfg.ip_options		= L_AND_R_IP_NO_ASSIG | 
-							    ENABLE_IP;
-			cfg.ip_local		= in_dev->ifa_list->ifa_local;
-			cfg.ip_remote		= in_dev->ifa_list->ifa_address;
-			/* Debugging code used to check that IP addresses
-                         * obtained from the kernel are correct */
-
-                        NEX_PRINTK(KERN_INFO "Local %u.%u.%u.%u Remote %u.%u.%u.%u Name %s\n",
-					NIPQUAD(ip_local),NIPQUAD(ip_remote), dev->name);
-			break;
-
-		case WANOPT_PPP_HOST:
-
-			printk(KERN_INFO "%s: PPP IP Mode: HOST\n",card->devname);
-			cfg.ip_options		= L_IP_LOCAL_ASSIG |
-						  R_IP_LOCAL_ASSIG | 
-						  ENABLE_IP;
-			cfg.ip_local		= in_dev->ifa_list->ifa_local;
-			cfg.ip_remote		= in_dev->ifa_list->ifa_address;
-			/* Debugging code used to check that IP addresses
-                         * obtained from the kernel are correct */
-                        NEX_PRINTK (KERN_INFO "Local %u.%u.%u.%u Remote %u.%u.%u.%u Name %s\n",
-					NIPQUAD(ip_local),NIPQUAD(ip_remote), dev->name);
-			
-			break;
-	
-		case WANOPT_PPP_PEER:
-
-			printk(KERN_INFO "%s: PPP IP Mode: PEER\n",card->devname);
-			cfg.ip_options		= L_IP_REMOTE_ASSIG | 
-						  R_IP_REMOTE_ASSIG | 
-							  ENABLE_IP;
-			cfg.ip_local		= 0x00;
-			cfg.ip_remote		= 0x00;
-			break;
-
-		default:
-			printk(KERN_INFO "%s: ERROR: Unsupported PPP Mode Selected\n",
-					card->devname);
-			printk(KERN_INFO "%s:        PPP IP Modes: STATIC, PEER or HOST\n",
-					card->devname);	
-			return 1;
-	}
-
-	return ppp_configure(card, &cfg);
-}
-
-/*============================================================================
- * Show disconnection cause.
- */
-static void show_disc_cause(sdla_t *card, unsigned cause)
-{
-	if (cause & 0x0802) 
-
-		printk(KERN_INFO "%s: link terminated by peer\n", 
-			card->devname);
-
-	else if (cause & 0x0004) 
-
-		printk(KERN_INFO "%s: link terminated by user\n", 
-			card->devname);
-
-	else if (cause & 0x0008) 
-
-		printk(KERN_INFO "%s: authentication failed\n", card->devname);
-	
-	else if (cause & 0x0010) 
-
-		printk(KERN_INFO 
-			"%s: authentication protocol negotiation failed\n", 
-			card->devname);
-
-	else if (cause & 0x0020) 
-		
-		printk(KERN_INFO
-		"%s: peer's request for authentication rejected\n",
-		card->devname);
-
-	else if (cause & 0x0040) 
-	
-		printk(KERN_INFO "%s: MRU option rejected by peer\n", 
-		card->devname);
-
-	else if (cause & 0x0080) 
-	
-		printk(KERN_INFO "%s: peer's MRU was too small\n", 
-		card->devname);
-
-	else if (cause & 0x0100) 
-
-		printk(KERN_INFO "%s: failed to negotiate peer's LCP options\n",
-		card->devname);
-
-	else if (cause & 0x0200) 
-		
-		printk(KERN_INFO "%s: failed to negotiate peer's IPCP options\n"
-		, card->devname);
-
-	else if (cause & 0x0400) 
-
-		printk(KERN_INFO 
-			"%s: failed to negotiate peer's IPXCP options\n",
-			card->devname);
-}
-
-/*=============================================================================
- * Process UDP call of type PTPIPEAB.
- */
-static void process_udp_mgmt_pkt(sdla_t *card, struct net_device *dev, 
-				 ppp_private_area_t *ppp_priv_area ) 
-{
-	unsigned char buf2[5];
-	unsigned char *buf;
-	unsigned int frames, len;
-	struct sk_buff *new_skb;
-	unsigned short data_length, buffer_length, real_len;
-	unsigned long data_ptr;
-	int udp_mgmt_req_valid = 1;
-	ppp_mbox_t *mbox = card->mbox;
-	struct timeval tv;
-	int err;
-	ppp_udp_pkt_t *ppp_udp_pkt = (ppp_udp_pkt_t*)&ppp_priv_area->udp_pkt_data;
-
-	memcpy(&buf2, &card->wandev.udp_port, 2 );
-
-
-	if(ppp_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-
-		switch(ppp_udp_pkt->cblock.command) {
-
-			case PPIPE_GET_IBA_DATA:
-			case PPP_READ_CONFIG:
-			case PPP_GET_CONNECTION_INFO:
-			case PPIPE_ROUTER_UP_TIME:
-			case PPP_READ_STATISTICS:
-			case PPP_READ_ERROR_STATS:
-			case PPP_READ_PACKET_STATS:
-			case PPP_READ_LCP_STATS:
-			case PPP_READ_IPCP_STATS:
-			case PPP_READ_IPXCP_STATS:
-			case PPP_READ_PAP_STATS:
-			case PPP_READ_CHAP_STATS:
-			case PPP_READ_CODE_VERSION:
-				udp_mgmt_req_valid = 1;
-				break;
-			   
-			default:
-				udp_mgmt_req_valid = 0;
-				break;
-		} 
-	}
-	
-  	if(!udp_mgmt_req_valid) {
-	    
-		/* set length to 0 */
-    		ppp_udp_pkt->cblock.length = 0x00;
-
-    		/* set return code */
-    		ppp_udp_pkt->cblock.result = 0xCD; 
-		++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_direction_err;
-	
-		if (net_ratelimit()){	
-			printk(KERN_INFO 
-			"%s: Warning, Illegal UDP command attempted from network: %x\n",
-			card->devname,ppp_udp_pkt->cblock.command);
-		}
-   	} else {
-		/* Initialize the trace element */
-		trace_element_t trace_element;		    
-
-		switch (ppp_udp_pkt->cblock.command){
-
-		/* PPIPE_ENABLE_TRACING */
-    		case PPIPE_ENABLE_TRACING:
-			if (!card->TracingEnabled) {
-    			
-				/* OPERATE_DATALINE_MONITOR */
-    				mbox->cmd.command = PPP_DATALINE_MONITOR;
-    				mbox->cmd.length = 0x01;
-    				mbox->data[0] = ppp_udp_pkt->data[0];
-	    			err = sdla_exec(mbox) ? 
-					mbox->cmd.result : CMD_TIMEOUT;
-	   
-				if (err != CMD_OK) { 
-	        			
-					ppp_error(card, err, mbox);
-	        			card->TracingEnabled = 0;
-	        		
-					/* set the return code */
-
-		        		ppp_udp_pkt->cblock.result = mbox->cmd.result;
-	        			mbox->cmd.length = 0;
-	        			break;
-	    			} 
-
-				sdla_peek(&card->hw, 0xC000, &buf2, 2);
-		    
-				ppp_priv_area->curr_trace_addr = 0;
-		    		memcpy(&ppp_priv_area->curr_trace_addr, &buf2, 2);
-		    		ppp_priv_area->start_trace_addr = 
-						ppp_priv_area->curr_trace_addr;
-				ppp_priv_area->end_trace_addr = 
-					ppp_priv_area->start_trace_addr + END_OFFSET;
-		    	
-				/* MAX_SEND_BUFFER_SIZE - 28 (IP header) 
-				   - 32 (ppipemon CBLOCK) */
-		    		available_buffer_space = MAX_LGTH_UDP_MGNT_PKT - 
-							 sizeof(ip_pkt_t)-
-							 sizeof(udp_pkt_t)-
-							 sizeof(wp_mgmt_t)-
-							 sizeof(cblock_t);
-	       	  	}
-	       	  	ppp_udp_pkt->cblock.result = 0;
-	       	  	mbox->cmd.length = 0;
-	       	  	card->TracingEnabled = 1;
-	       	  	break;
-	   
-		/* PPIPE_DISABLE_TRACING */
-		case PPIPE_DISABLE_TRACING:
-	      		
-			if(card->TracingEnabled) {
-		   	
-				/* OPERATE_DATALINE_MONITOR */
-		    		mbox->cmd.command = 0x33;
-		    		mbox->cmd.length = 1;
-		    		mbox->data[0] = 0x00;
-		    		err = sdla_exec(mbox) ? 
-					mbox->cmd.result : CMD_TIMEOUT;
-	       	  
-			} 
-		
-			/*set return code*/
-			ppp_udp_pkt->cblock.result = 0;
-			mbox->cmd.length = 0;
-			card->TracingEnabled = 0;
-			break;
-	   
-		/* PPIPE_GET_TRACE_INFO */
-		case PPIPE_GET_TRACE_INFO:
-
-			if(!card->TracingEnabled) {
-				/* set return code */
-	    			ppp_udp_pkt->cblock.result = 1;
-	    			mbox->cmd.length = 0;
-			}		    
-
-			buffer_length = 0;
-			
-			/* frames < 62, where 62 is the number of trace
-			   information elements.  There is in total 496
-			   bytes of space and each trace information
-			   element is 8 bytes. 
-			 */
-			for ( frames=0; frames<62; frames++) {
-	
-				trace_pkt_t *trace_pkt = (trace_pkt_t *)
-					&ppp_udp_pkt->data[buffer_length];
-	
-				/* Read the whole trace packet */
-				sdla_peek(&card->hw, ppp_priv_area->curr_trace_addr, 
-					  &trace_element, sizeof(trace_element_t));
-	
-				/* no data on board so exit */
-				if( trace_element.opp_flag == 0x00 ) 
-					break;
-	      
-				data_ptr = trace_element.trace_data_ptr;
-
-				/* See if there is actual data on the trace buffer */
-				if (data_ptr){
-					data_length = trace_element.trace_length;
-				}else{
-					data_length = 0;
-					ppp_udp_pkt->data[0] |= 0x02;
-				}
-
-				//FIXME: Do we need this check
-				if ((available_buffer_space - buffer_length) 
-				     < (sizeof(trace_element_t)+1)){
-					
-					/*indicate we have more frames 
-					 * on board and exit 
-					 */
-					ppp_udp_pkt->data[0] |= 0x02;
-					break;
-				}
-				
-				trace_pkt->status = trace_element.trace_type;
-				trace_pkt->time_stamp = trace_element.trace_time_stamp;
-				trace_pkt->real_length = trace_element.trace_length;
-
-				real_len = trace_element.trace_length;	
-				
-				if(data_ptr == 0){
-					trace_pkt->data_avail = 0x00;
-				}else{
-					/* we can take it next time */
-					if ((available_buffer_space - buffer_length)<
-						(real_len + sizeof(trace_pkt_t))){
-					
-						ppp_udp_pkt->data[0] |= 0x02;
-						break;
-					} 
-					trace_pkt->data_avail = 0x01;
-				
-					/* get the data */
-					sdla_peek(&card->hw, data_ptr, 
-						  &trace_pkt->data,
-						  real_len);
-				}	
-				/* zero the opp flag to 
-				   show we got the frame */
-				buf2[0] = 0x00;
-				sdla_poke(&card->hw, ppp_priv_area->curr_trace_addr,
-					  &buf2, 1);
-
-				/* now move onto the next 
-				   frame */
-				ppp_priv_area->curr_trace_addr += 8;
-
-				/* check if we passed the last address */
-				if ( ppp_priv_area->curr_trace_addr >= 
-					ppp_priv_area->end_trace_addr){
-
-					ppp_priv_area->curr_trace_addr = 
-						ppp_priv_area->start_trace_addr;
-				}
- 
-				/* update buffer length and make sure its even */ 
-
-				if ( trace_pkt->data_avail == 0x01 ) {
-					buffer_length += real_len - 1;
-				}
- 
-				/* for the header */
-				buffer_length += 8;
-
-				if( buffer_length & 0x0001 )
-					buffer_length += 1;
-			}
-
-			/* ok now set the total number of frames passed
-			   in the high 5 bits */
-			ppp_udp_pkt->data[0] |= (frames << 2);
-	 
-			/* set the data length */
-			mbox->cmd.length = buffer_length;
-			ppp_udp_pkt->cblock.length = buffer_length;
-	 
-			/* set return code */
-			ppp_udp_pkt->cblock.result = 0;
-	      	  	break;
-
-   		/* PPIPE_GET_IBA_DATA */
-		case PPIPE_GET_IBA_DATA:
-	        
-			mbox->cmd.length = 0x09;
-		
-			sdla_peek(&card->hw, 0xF003, &ppp_udp_pkt->data, 
-					mbox->cmd.length);
-	        
-			/* set the length of the data */
-			ppp_udp_pkt->cblock.length = 0x09;
-
-			/* set return code */
-			ppp_udp_pkt->cblock.result = 0x00;
-			ppp_udp_pkt->cblock.result = 0;
-			break;
-
-		/* PPIPE_FT1_READ_STATUS */
-		case PPIPE_FT1_READ_STATUS:
-			sdla_peek(&card->hw, 0xF020, &ppp_udp_pkt->data[0], 2);
-			ppp_udp_pkt->cblock.length = mbox->cmd.length = 2;
-			ppp_udp_pkt->cblock.result = 0;
-			break;
-		
-		case PPIPE_FLUSH_DRIVER_STATS:   
-			init_ppp_priv_struct( ppp_priv_area );
-			init_global_statistics( card );
-			mbox->cmd.length = 0;
-			ppp_udp_pkt->cblock.result = 0;
-			break;
-
-		
-		case PPIPE_ROUTER_UP_TIME:
-
-			do_gettimeofday( &tv );
-			ppp_priv_area->router_up_time = tv.tv_sec - 
-					ppp_priv_area->router_start_time;
-			*(unsigned long *)&ppp_udp_pkt->data = ppp_priv_area->router_up_time;
-			mbox->cmd.length = 4;
-			ppp_udp_pkt->cblock.result = 0;
-			break;
-
-				/* PPIPE_DRIVER_STATISTICS */   
-		case PPIPE_DRIVER_STAT_IFSEND:
-			memcpy(&ppp_udp_pkt->data, &ppp_priv_area->if_send_stat, 
-				sizeof(if_send_stat_t));
-
-
-			ppp_udp_pkt->cblock.result = 0;
-			ppp_udp_pkt->cblock.length = sizeof(if_send_stat_t);
-			mbox->cmd.length = sizeof(if_send_stat_t);	
-			break;
-
-		case PPIPE_DRIVER_STAT_INTR:
-			memcpy(&ppp_udp_pkt->data, &card->statistics, 
-				sizeof(global_stats_t));
-
-			memcpy(&ppp_udp_pkt->data+sizeof(global_stats_t),
-				&ppp_priv_area->rx_intr_stat,
-				sizeof(rx_intr_stat_t));
-
-			ppp_udp_pkt->cblock.result = 0;
-			ppp_udp_pkt->cblock.length = sizeof(global_stats_t)+
-						     sizeof(rx_intr_stat_t);
-			mbox->cmd.length = ppp_udp_pkt->cblock.length;
-			break;
-
-		case PPIPE_DRIVER_STAT_GEN:
-			memcpy( &ppp_udp_pkt->data,
-				&ppp_priv_area->pipe_mgmt_stat,
-				sizeof(pipe_mgmt_stat_t));
-
-			memcpy(&ppp_udp_pkt->data+sizeof(pipe_mgmt_stat_t), 
-			       &card->statistics, sizeof(global_stats_t));
-
-			ppp_udp_pkt->cblock.result = 0;
-			ppp_udp_pkt->cblock.length = sizeof(global_stats_t)+
-						     sizeof(rx_intr_stat_t);
-			mbox->cmd.length = ppp_udp_pkt->cblock.length;
-			break;
-
-
-		/* FT1 MONITOR STATUS */
-   		case FT1_MONITOR_STATUS_CTRL:
-	
-			/* Enable FT1 MONITOR STATUS */
-	        	if( ppp_udp_pkt->data[0] == 1) {
-			
-				if( rCount++ != 0 ) {
-		        		ppp_udp_pkt->cblock.result = 0;
-	          			mbox->cmd.length = 1;
-		  			break;
-		    		}	
-	      		}
-
-	      		/* Disable FT1 MONITOR STATUS */
-	      		if( ppp_udp_pkt->data[0] == 0) {
-
-	      	   		if( --rCount != 0) {
-		  			ppp_udp_pkt->cblock.result = 0;
-		  			mbox->cmd.length = 1;
-		  			break;
-	   	    		} 
-	      		} 	
-			goto udp_dflt_cmd;
-			
-		/* WARNING: FIXME: This should be fixed.
-		 * The FT1 Status Ctrl doesn't have a break
-                 * statment.  Thus, no code must be inserted
-                 * HERE: between default and above case statement */
-
-		default:
-udp_dflt_cmd:
-	        
-			/* it's a board command */
-			mbox->cmd.command = ppp_udp_pkt->cblock.command;
-			mbox->cmd.length = ppp_udp_pkt->cblock.length;
- 
-			if(mbox->cmd.length) {
-				memcpy(&mbox->data,(unsigned char *)ppp_udp_pkt->data,
-				       mbox->cmd.length);
-	      		} 
-	          
-			/* run the command on the board */
-			err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-		
-			if (err != CMD_OK) {
-		
-		    		ppp_error(card, err, mbox);
-		    		++ppp_priv_area->pipe_mgmt_stat.
-					 UDP_PIPE_mgmt_adptr_cmnd_timeout;
-				break;
-			}
-	          
-		  	++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_cmnd_OK;
-		
-			/* copy the result back to our buffer */
-			memcpy(&ppp_udp_pkt->cblock,mbox, sizeof(cblock_t));
-	          
-			if(mbox->cmd.length) {
-				memcpy(&ppp_udp_pkt->data,&mbox->data,mbox->cmd.length);
-			} 
-
-		} /* end of switch */
-     	} /* end of else */
-
-     	/* Fill UDP TTL */
-     	ppp_udp_pkt->ip_pkt.ttl = card->wandev.ttl; 
-     	len = reply_udp(ppp_priv_area->udp_pkt_data, mbox->cmd.length);
-
-     	if (ppp_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-
-		/* Make sure we are not already sending */
-		if (!test_bit(SEND_CRIT,&card->wandev.critical)){
-			++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_adptr;
-			ppp_send(card,ppp_priv_area->udp_pkt_data,len,ppp_priv_area->protocol);
-		}
-
-	} else {	
-	
-		/* Pass it up the stack
-    		   Allocate socket buffer */
-		if ((new_skb = dev_alloc_skb(len)) != NULL) {
-	    	
-			/* copy data into new_skb */
-
-  	    		buf = skb_put(new_skb, len);
-  	    		memcpy(buf,ppp_priv_area->udp_pkt_data, len);
-
-	    		++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_stack;
-			
-            		/* Decapsulate packet and pass it up the protocol 
-			   stack */
-	    		new_skb->protocol = htons(ETH_P_IP);
-            		new_skb->dev = dev;
-	    		new_skb->mac.raw  = new_skb->data;
-			netif_rx(new_skb);
-			dev->last_rx = jiffies;
-		
-		} else {
-	    	
-			++ppp_priv_area->pipe_mgmt_stat.UDP_PIPE_mgmt_no_socket;
-			printk(KERN_INFO "no socket buffers available!\n");
-  		}
-    	}	
-
-	ppp_priv_area->udp_pkt_lgth = 0;
-	
-	return; 
-}
-
-/*=============================================================================
- * Initial the ppp_private_area structure.
- */
-static void init_ppp_priv_struct( ppp_private_area_t *ppp_priv_area )
-{
-
-	memset(&ppp_priv_area->if_send_stat, 0, sizeof(if_send_stat_t));
-	memset(&ppp_priv_area->rx_intr_stat, 0, sizeof(rx_intr_stat_t));
-	memset(&ppp_priv_area->pipe_mgmt_stat, 0, sizeof(pipe_mgmt_stat_t));	
-}
-
-/*============================================================================
- * Initialize Global Statistics
- */
-static void init_global_statistics( sdla_t *card )
-{
-	memset(&card->statistics, 0, sizeof(global_stats_t));
-}
-
-/*============================================================================
- * Initialize Receive and Transmit Buffers.
- */
-static void init_ppp_tx_rx_buff( sdla_t *card )
-{
-	ppp508_buf_info_t* info;
-
-	if (card->hw.type == SDLA_S514) {
-		
-		info = (void*)(card->hw.dpmbase + PPP514_BUF_OFFS);
-
-       		card->u.p.txbuf_base = (void*)(card->hw.dpmbase +
-			info->txb_ptr);
-
-                card->u.p.txbuf_last = (ppp_buf_ctl_t*)card->u.p.txbuf_base +
-                        (info->txb_num - 1);
-
-                card->u.p.rxbuf_base = (void*)(card->hw.dpmbase +
-                        info->rxb_ptr);
-
-                card->u.p.rxbuf_last = (ppp_buf_ctl_t*)card->u.p.rxbuf_base +
-                        (info->rxb_num - 1);
-
-	} else {
-		
-		info = (void*)(card->hw.dpmbase + PPP508_BUF_OFFS);
-
-		card->u.p.txbuf_base = (void*)(card->hw.dpmbase +
-			(info->txb_ptr - PPP508_MB_VECT));
-
-		card->u.p.txbuf_last = (ppp_buf_ctl_t*)card->u.p.txbuf_base +
-			(info->txb_num - 1);
-
-		card->u.p.rxbuf_base = (void*)(card->hw.dpmbase +
-			(info->rxb_ptr - PPP508_MB_VECT));
-
-		card->u.p.rxbuf_last = (ppp_buf_ctl_t*)card->u.p.rxbuf_base +
-			(info->rxb_num - 1);
-	}
-
-	card->u.p.txbuf_next = (unsigned long*)&info->txb_nxt; 
-	card->u.p.rxbuf_next = (unsigned long*)&info->rxb1_ptr;
-
-	card->u.p.rx_base = info->rxb_base;
-        card->u.p.rx_top  = info->rxb_end;
-      
-	card->u.p.txbuf = card->u.p.txbuf_base;
-	card->rxmb = card->u.p.rxbuf_base;
-
-}
-
-/*=============================================================================
- * Read Connection Information (ie for Remote IP address assginment).
- * Called when ppp interface connected.
- */
-static int read_info( sdla_t *card )
-{
-	struct net_device *dev = card->wandev.dev;
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	int err;
-
-	struct ifreq if_info;
-	struct sockaddr_in *if_data1, *if_data2;
-	mm_segment_t fs;
-
-	/* Set Local and remote addresses */
-	memset(&if_info, 0, sizeof(if_info));
-	strcpy(if_info.ifr_name, dev->name);
-
-
-	fs = get_fs();
-	set_fs(get_ds());     /* get user space block */ 
-
-	/* Change the local and remote ip address of the interface.
-	 * This will also add in the destination route.
-	 */	
-	if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
-	if_data1->sin_addr.s_addr = ppp_priv_area->ip_local;
-	if_data1->sin_family = AF_INET;
-	err = devinet_ioctl( SIOCSIFADDR, &if_info );
-	if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
-	if_data2->sin_addr.s_addr = ppp_priv_area->ip_remote;
-	if_data2->sin_family = AF_INET;
-	err = devinet_ioctl( SIOCSIFDSTADDR, &if_info );
-
-	set_fs(fs);           /* restore old block */
-	
-	if (err) {
-		printk (KERN_INFO "%s: Adding of route failed: %i\n",
-			card->devname,err);
-		printk (KERN_INFO "%s:	Local : %u.%u.%u.%u\n",
-			card->devname,NIPQUAD(ppp_priv_area->ip_local));
-		printk (KERN_INFO "%s:	Remote: %u.%u.%u.%u\n",
-			card->devname,NIPQUAD(ppp_priv_area->ip_remote));
-	}
-	return err;
-}
-
-/*=============================================================================
- * Remove Dynamic Route.
- * Called when ppp interface disconnected.
- */
-
-static void remove_route( sdla_t *card )
-{
-
-	struct net_device *dev = card->wandev.dev;
-	long ip_addr;
-	int err;
-
-        mm_segment_t fs;
-	struct ifreq if_info;
-	struct sockaddr_in *if_data1;
-        struct in_device *in_dev = dev->ip_ptr;
-        struct in_ifaddr *ifa = in_dev->ifa_list;	
-
-	ip_addr = ifa->ifa_local;
-
-	/* Set Local and remote addresses */
-	memset(&if_info, 0, sizeof(if_info));
-	strcpy(if_info.ifr_name, dev->name);
-
-	fs = get_fs();
-       	set_fs(get_ds());     /* get user space block */ 
-
-	/* Change the local ip address of the interface to 0.
-	 * This will also delete the destination route.
-	 */	
-	if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
-	if_data1->sin_addr.s_addr = 0;
-	if_data1->sin_family = AF_INET;
-	err = devinet_ioctl( SIOCSIFADDR, &if_info );
-
-        set_fs(fs);           /* restore old block */
-
-	
-	if (err) {
-		printk (KERN_INFO "%s: Deleting dynamic route failed %d!\n",
-			 card->devname, err);
-		return;
-	}else{
-		printk (KERN_INFO "%s: PPP Deleting dynamic route %u.%u.%u.%u successfuly\n",
-			card->devname, NIPQUAD(ip_addr));
-	}
-	return;
-}
-
-/*=============================================================================
- * Perform the Interrupt Test by running the READ_CODE_VERSION command MAX_INTR
- * _TEST_COUNTER times.
- */
-static int intr_test( sdla_t *card )
-{
-	ppp_mbox_t *mb = card->mbox;
-	int err,i;
-
-	err = ppp_set_intr_mode( card, 0x08 );
-	
-	if (err == CMD_OK) { 
-		
-		for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {	
-			/* Run command READ_CODE_VERSION */
-			memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-			mb->cmd.length  = 0;
-			mb->cmd.command = PPP_READ_CODE_VERSION;
-			err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-			if (err != CMD_OK) 
-				ppp_error(card, err, mb);
-		}
-	}
-	else return err;
-
-	err = ppp_set_intr_mode( card, 0 );
-	if (err != CMD_OK) 
-		return err;
-
-	return 0;
-}
-
-/*==============================================================================
- * Determine what type of UDP call it is. DRVSTATS or PTPIPEAB ?
- */
-static int udp_pkt_type( struct sk_buff *skb, sdla_t *card )
-{
-	unsigned char *sendpacket;
-	unsigned char buf2[5]; 
-	ppp_udp_pkt_t *ppp_udp_pkt = (ppp_udp_pkt_t *)skb->data; 
-	
-	sendpacket = skb->data;
-	memcpy(&buf2, &card->wandev.udp_port, 2);
-	
-	if( 	ppp_udp_pkt->ip_pkt.ver_inet_hdr_length  == 0x45 &&        /* IP packet */ 
-		sendpacket[9]  == 0x11 &&        /* UDP packet */
-		sendpacket[22] == buf2[1] &&     /* UDP Port */
-		sendpacket[23] == buf2[0] &&
-		sendpacket[36] == 0x01 ) {
-	
-		if (    sendpacket[28] == 0x50 &&    /* PTPIPEAB: Signature */ 
-			sendpacket[29] == 0x54 &&      
-			sendpacket[30] == 0x50 &&      
-			sendpacket[31] == 0x49 &&      
-			sendpacket[32] == 0x50 &&      
-			sendpacket[33] == 0x45 &&      
-			sendpacket[34] == 0x41 &&      
-			sendpacket[35] == 0x42 ){ 
-
-			return UDP_PTPIPE_TYPE;
-	
-		} else if(sendpacket[28] == 0x44 &&  /* DRVSTATS: Signature */
-			sendpacket[29] == 0x52 &&      
-      			sendpacket[30] == 0x56 &&      
-      			sendpacket[31] == 0x53 &&      
-      			sendpacket[32] == 0x54 &&      
-      			sendpacket[33] == 0x41 &&      
-      			sendpacket[34] == 0x54 &&      
-      			sendpacket[35] == 0x53 ){
-	
-			return UDP_DRVSTATS_TYPE;
-
-		} else
-			return UDP_INVALID_TYPE;
-
-	} else
-		return UDP_INVALID_TYPE;
-
-}
-
-/*============================================================================
- * 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;
-        struct in_device *in_dev;
-
-        /* read the IP source address from the outgoing packet */
-        src_ip_addr = *(u32 *)(skb->data + 12);
-
-	/* read the IP broadcast address for the device */
-        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;
-        }
- 
-        /* 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;
-}
-
-void s508_lock (sdla_t *card, unsigned long *smp_flags)
-{
-	spin_lock_irqsave(&card->wandev.lock, *smp_flags);
-}
-
-void s508_unlock (sdla_t *card, unsigned long *smp_flags)
-{
-        spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
-}
-
-static int read_connection_info (sdla_t *card)
-{
-	ppp_mbox_t *mb = card->mbox;
-	struct net_device *dev = card->wandev.dev;
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-	ppp508_connect_info_t *ppp508_connect_info;
-	int err;
-
-	memset(&mb->cmd, 0, sizeof(ppp_cmd_t));
-	mb->cmd.length  = 0;
-	mb->cmd.command = PPP_GET_CONNECTION_INFO;
-	err = sdla_exec(mb) ? mb->cmd.result : CMD_TIMEOUT;
-
-	if (err != CMD_OK) { 
-		ppp_error(card, err, mb);
-		ppp_priv_area->ip_remote = 0;
-		ppp_priv_area->ip_local = 0;
-	}
-	else {
-		ppp508_connect_info = (ppp508_connect_info_t *)mb->data;
-		ppp_priv_area->ip_remote = ppp508_connect_info->ip_remote;
-		ppp_priv_area->ip_local = ppp508_connect_info->ip_local;
-
-		NEX_PRINTK(KERN_INFO "READ CONNECTION GOT IP ADDRESS %x, %x\n",
-				ppp_priv_area->ip_remote,
-				ppp_priv_area->ip_local);
-	}
-
-	return err;
-}
-
-/*===============================================================================
- * config_ppp
- *
- *	Configure the ppp protocol and enable communications.		
- *
- *   	The if_open function binds this function to the poll routine.
- *      Therefore, this function will run every time the ppp interface
- *      is brought up.  
- *      
- *	If the communications are not enabled, proceed to configure
- *      the card and enable communications.
- *
- *      If the communications are enabled, it means that the interface
- *      was shutdown by ether the user or driver. In this case, we 
- *      have to check that the IP addresses have not changed.  If
- *      the IP addresses changed, we have to reconfigure the firmware
- *      and update the changed IP addresses.  Otherwise, just exit.
- */
-static int config_ppp (sdla_t *card)
-{
-
-	struct net_device *dev = card->wandev.dev;
-	ppp_flags_t *flags = card->flags;
-	ppp_private_area_t *ppp_priv_area = dev->priv;
-
-	if (card->u.p.comm_enabled){
-
-		if (ppp_priv_area->ip_local_tmp != ppp_priv_area->ip_local ||
-		    ppp_priv_area->ip_remote_tmp != ppp_priv_area->ip_remote){
-			
-			/* The IP addersses have changed, we must
-                         * stop the communications and reconfigure
-                         * the card. Reason: the firmware must know
-                         * the local and remote IP addresses. */
-			disable_comm(card);
-			wanpipe_set_state(card, WAN_DISCONNECTED);
-			printk(KERN_INFO 
-				"%s: IP addresses changed!\n",
-					card->devname);
-			printk(KERN_INFO "%s: Restarting communications ...\n",
-					card->devname);
-		}else{ 
-			/* IP addresses are the same and the link is up, 
-                         * we don't have to do anything here. Therefore, exit */
-			return 0;
-		}
-	}
-
-	/* Record the new IP addreses */
-	ppp_priv_area->ip_local = ppp_priv_area->ip_local_tmp;
-	ppp_priv_area->ip_remote = ppp_priv_area->ip_remote_tmp;
-
-	if (config508(dev, card)){
-		printk(KERN_INFO "%s: Failed to configure PPP device\n",
-			card->devname);
-		return 0;
-	}
-
-	if (ppp_set_intr_mode(card, PPP_INTR_RXRDY|
-			    		PPP_INTR_TXRDY|
-				    	PPP_INTR_MODEM|
-				    	PPP_INTR_DISC |
-				    	PPP_INTR_OPEN |
-				    	PPP_INTR_DROP_DTR |
-					PPP_INTR_TIMER)) {
-
-		printk(KERN_INFO "%s: Failed to configure board interrupts !\n", 
-			card->devname);
-		return 0;
-	}
-
-        /* Turn off the transmit and timer interrupt */
-	flags->imask &= ~(PPP_INTR_TXRDY | PPP_INTR_TIMER) ;
-
-
-	/* If you are not the authenticator and any one of the protocol is 
-	 * enabled then we call the set_out_bound_authentication.
-	 */
-	if ( !card->u.p.authenticator  && (ppp_priv_area->pap || ppp_priv_area->chap)) {
-		if ( ppp_set_outbnd_auth(card, ppp_priv_area) ){
-			printk(KERN_INFO "%s: Outbound authentication failed !\n",
-				card->devname);
-			return 0;
-		}
-	} 
-	
-	/* If you are the authenticator and any one of the protocol is enabled
-	 * then we call the set_in_bound_authentication.
-	 */
-	if (card->u.p.authenticator && (ppp_priv_area->pap || ppp_priv_area->chap)){
-		if (ppp_set_inbnd_auth(card, ppp_priv_area)){
-			printk(KERN_INFO "%s: Inbound authentication failed !\n",
-				card->devname);	
-			return 0;
-		}
-	}
-
-	/* If we fail to enable communications here it's OK,
-	 * since the DTR timer will cause a disconnected, which
-	 * will retrigger communication in timer_intr() */
-	if (ppp_comm_enable(card) == CMD_OK) {
-		wanpipe_set_state(card, WAN_CONNECTING);
-		init_ppp_tx_rx_buff(card);
-	}
-
-	return 0; 
-}
-
-/*============================================================
- * ppp_poll
- *	
- * Rationale:
- * 	We cannot manipulate the routing tables, or
- *      ip addresses withing the interrupt. Therefore
- *      we must perform such actons outside an interrupt 
- *      at a later time. 
- *
- * Description:	
- *	PPP polling routine, responsible for 
- *     	shutting down interfaces upon disconnect
- *     	and adding/removing routes. 
- *      
- * Usage:        
- * 	This function is executed for each ppp  
- * 	interface through a tq_schedule bottom half.
- *      
- *      trigger_ppp_poll() function is used to kick
- *      the ppp_poll routine.  
- */
-static void ppp_poll(struct net_device *dev)
-{
-	ppp_private_area_t *ppp_priv_area; 	
-	sdla_t *card;
-	u8 check_gateway=0;
-	ppp_flags_t *flags;
-
-	if (!dev || (ppp_priv_area = dev->priv) == NULL)
-		return;
-
-	card = ppp_priv_area->card;
-	flags = card->flags;
-
-	/* Shutdown is in progress, stop what you are 
-	 * doing and get out */
-	if (test_bit(PERI_CRIT,&card->wandev.critical)){
-		clear_bit(POLL_CRIT,&card->wandev.critical);
-		return;
-	}
-
-	/* if_open() function has triggered the polling routine
-	 * to determine the configured IP addresses.  Once the
-	 * addresses are found, trigger the chdlc configuration */
-	if (test_bit(0,&ppp_priv_area->config_ppp)){
-
-		ppp_priv_area->ip_local_tmp  = get_ip_address(dev,WAN_LOCAL_IP);
-		ppp_priv_area->ip_remote_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP);
-
-		if (ppp_priv_area->ip_local_tmp == ppp_priv_area->ip_remote_tmp && 
-	            card->u.p.ip_mode == WANOPT_PPP_HOST){
-			
-			if (++ppp_priv_area->ip_error > MAX_IP_ERRORS){
-				printk(KERN_INFO "\n%s: --- WARNING ---\n",
-						card->devname);
-				printk(KERN_INFO "%s: The local IP address is the same as the\n",
-						card->devname);
-				printk(KERN_INFO "%s: Point-to-Point IP address.\n",
-						card->devname);
-				printk(KERN_INFO "%s: --- WARNING ---\n\n",
-						card->devname);
-			}else{
-				clear_bit(POLL_CRIT,&card->wandev.critical);
-				ppp_priv_area->poll_delay_timer.expires = jiffies+HZ;
-				add_timer(&ppp_priv_area->poll_delay_timer);
-				return;
-			}
-		}
-
-		ppp_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
-		flags->imask |= PPP_INTR_TIMER;	
-		ppp_priv_area->ip_error=0;	
-		
-		clear_bit(0,&ppp_priv_area->config_ppp);
-		clear_bit(POLL_CRIT,&card->wandev.critical);
-		return;
-	}
-
-	/* Dynamic interface implementation, as well as dynamic
-	 * routing.  */
-	
-	switch (card->wandev.state) {
-	
-	case WAN_DISCONNECTED:
-
-		/* If the dynamic interface configuration is on, and interface 
-		 * is up, then bring down the netowrk interface */
-
-		if (test_bit(DYN_OPT_ON,&ppp_priv_area->interface_down) &&
-		    !test_bit(DEV_DOWN,&ppp_priv_area->interface_down)	&&	
-		    card->wandev.dev->flags & IFF_UP){	
-
-			printk(KERN_INFO "%s: Interface %s down.\n",
-				card->devname,card->wandev.dev->name);
-			change_dev_flags(card->wandev.dev,
-					(card->wandev.dev->flags&~IFF_UP));
-			set_bit(DEV_DOWN,&ppp_priv_area->interface_down);
-		}else{
-			/* We need to check if the local IP address is
-               	   	 * zero. If it is, we shouldn't try to remove it.
-                 	 * For some reason the kernel crashes badly if 
-                 	 * we try to remove the route twice */
-
-			if (card->wandev.dev->flags & IFF_UP && 
-		    	    get_ip_address(card->wandev.dev,WAN_LOCAL_IP) &&
-		    	    card->u.p.ip_mode == WANOPT_PPP_PEER){
-
-				remove_route(card);
-			}
-		}
-		break;
-
-	case WAN_CONNECTED:
-		
-		/* In SMP machine this code can execute before the interface
-		 * comes up.  In this case, we must make sure that we do not
-		 * try to bring up the interface before dev_open() is finished */
-
-
-		/* DEV_DOWN will be set only when we bring down the interface
-		 * for the very first time. This way we know that it was us
-		 * that brought the interface down */
-		
-		if (test_bit(DYN_OPT_ON,&ppp_priv_area->interface_down) &&
-	            test_bit(DEV_DOWN,  &ppp_priv_area->interface_down) &&
- 		    !(card->wandev.dev->flags & IFF_UP)){
-			
-			printk(KERN_INFO "%s: Interface %s up.\n",
-				card->devname,card->wandev.dev->name);
-			
-			change_dev_flags(card->wandev.dev,(card->wandev.dev->flags|IFF_UP));
-			clear_bit(DEV_DOWN,&ppp_priv_area->interface_down);
-			check_gateway=1;
-		}
-
-		if ((card->u.p.ip_mode == WANOPT_PPP_PEER) && 
-		    test_bit(1,&Read_connection_info)) { 
-			
-			process_route(card);
-			clear_bit(1,&Read_connection_info);
-			check_gateway=1;
-		}
-
-		if (ppp_priv_area->gateway && check_gateway)
-			add_gateway(card,dev);
-
-		break;
-	}
-	clear_bit(POLL_CRIT,&card->wandev.critical);
-	return;
-}
-
-/*============================================================
- * trigger_ppp_poll
- *
- * Description:
- * 	Add a ppp_poll() task into a tq_scheduler bh handler
- *      for a specific interface.  This will kick
- *      the ppp_poll() routine at a later time. 
- *
- * Usage:
- * 	Interrupts use this to defer a taks to 
- *      a polling routine.
- *
- */	
-
-static void trigger_ppp_poll(struct net_device *dev)
-{
-	ppp_private_area_t *ppp_priv_area;
-	if ((ppp_priv_area=dev->priv) != NULL){ 	
-		
-		sdla_t *card = ppp_priv_area->card;
-
-		if (test_bit(PERI_CRIT,&card->wandev.critical)){
-			return;
-		}
-		
-		if (test_and_set_bit(POLL_CRIT,&card->wandev.critical)){
-			return;
-		}
-
-		schedule_work(&ppp_priv_area->poll_work);
-	}
-	return;
-}
-
-static void ppp_poll_delay (unsigned long dev_ptr)
-{
-	struct net_device *dev = (struct net_device *)dev_ptr;
-	trigger_ppp_poll(dev);
-}
-
-/*============================================================
- * detect_and_fix_tx_bug
- *
- * Description:
- *	On connect, if the board tx buffer ptr is not the same
- *      as the driver tx buffer ptr, we found a firmware bug.
- *      Report the bug to the above layer.  To fix the
- *      error restart communications again.
- *
- * Usage:
- *
- */	
-
-static int detect_and_fix_tx_bug (sdla_t *card)
-{
-	if (((unsigned long)card->u.p.txbuf_base&0xFFF) != ((*card->u.p.txbuf_next)&0xFFF)){
-		NEX_PRINTK(KERN_INFO "Major Error, Fix the bug\n");
-		return 1;
-	}
-	return 0;
-}
-
-MODULE_LICENSE("GPL");
-
-/****** End *****************************************************************/
diff --git a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c
deleted file mode 100644
index 63f846d..0000000
--- a/drivers/net/wan/sdla_x25.c
+++ /dev/null
@@ -1,5497 +0,0 @@
-/*****************************************************************************
-* sdla_x25.c	WANPIPE(tm) Multiprotocol WAN Link Driver.  X.25 module.
-*
-* Author:	Nenad Corbic	<ncorbic@sangoma.com>
-*
-* Copyright:	(c) 1995-2001 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.
-* ============================================================================
-* Apr 03, 2001  Nenad Corbic	 o Fixed the rx_skb=NULL bug in x25 in rx_intr().
-* Dec 26, 2000  Nenad Corbic	 o Added a new polling routine, that uses
-*                                  a kernel timer (more efficient).
-* Dec 25, 2000  Nenad Corbic	 o Updated for 2.4.X kernel
-* Jul 26, 2000  Nenad Corbic	 o Increased the local packet buffering
-* 				   for API to 4096+header_size. 
-* Jul 17, 2000  Nenad Corbic	 o Fixed the x25 startup bug. Enable 
-* 				   communications only after all interfaces
-* 				   come up.  HIGH SVC/PVC is used to calculate
-* 				   the number of channels.
-*                                  Enable protocol only after all interfaces
-*                                  are enabled.
-* Jul 10, 2000	Nenad Corbic	 o Fixed the M_BIT bug. 
-* Apr 25, 2000  Nenad Corbic	 o Pass Modem messages to the API.
-*                                  Disable idle timeout in X25 API.
-* Apr 14, 2000  Nenad Corbic	 o Fixed: Large LCN number support.
-*                                  Maximum LCN number is 4095.
-*                                  Maximum number of X25 channels is 255.
-* Apr 06, 2000  Nenad Corbic	 o Added SMP Support.
-* Mar 29, 2000  Nenad Corbic	 o Added support for S514 PCI Card
-* Mar 23, 2000  Nenad Corbic	 o Improved task queue, BH handling.
-* Mar 14, 2000  Nenad Corbic  	 o Updated Protocol Violation handling
-*                                  routines.  Bug Fix.
-* Mar 10, 2000  Nenad Corbic	 o Bug Fix: corrupted mbox recovery.
-* Mar 09, 2000  Nenad Corbic     o Fixed the auto HDLC bug.
-* Mar 08, 2000	Nenad Corbic     o Fixed LAPB HDLC startup problems.
-*                                  Application must bring the link up 
-*                                  before tx/rx, and bring the 
-*                                  link down on close().
-* Mar 06, 2000	Nenad Corbic	 o Added an option for logging call setup 
-*                                  information. 
-* Feb 29, 2000  Nenad Corbic 	 o Added support for LAPB HDLC API
-* Feb 25, 2000  Nenad Corbic     o Fixed the modem failure handling.
-*                                  No Modem OOB message will be passed 
-*                                  to the user.
-* Feb 21, 2000  Nenad Corbic 	 o Added Xpipemon Debug Support
-* Dec 30, 1999 	Nenad Corbic	 o Socket based X25API 
-* Sep 17, 1998	Jaspreet Singh	 o Updates for 2.2.X  kernel
-* Mar 15, 1998	Alan Cox	 o 2.1.x porting
-* Dec 19, 1997	Jaspreet Singh	 o Added multi-channel IPX support
-* 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.
-*****************************************************************************/
-
-/*======================================================
- * 	Includes 
- *=====================================================*/
-
-#include <linux/module.h>
-#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/ctype.h>
-#include <linux/slab.h>	/* kmalloc(), kfree() */
-#include <linux/wanrouter.h>	/* WAN router definitions */
-#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
-#include <linux/workqueue.h>
-#include <linux/jiffies.h>	/* time_after() macro */
-#include <asm/byteorder.h>	/* htons(), etc. */
-#include <asm/atomic.h>
-#include <linux/delay.h>	/* Experimental delay */
-
-#include <asm/uaccess.h>
-
-#include <linux/if.h>
-#include <linux/if_arp.h>
-#include <linux/sdla_x25.h>	/* X.25 firmware API definitions */
-#include <linux/if_wanpipe_common.h>
-#include <linux/if_wanpipe.h>
-
-
-/*======================================================
- * 	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 */
-#define MAX_BH_BUFF	10
-#define M_BIT		0x01	
-
-//#define PRINT_DEBUG 1
-#ifdef PRINT_DEBUG
-#define DBG_PRINTK(format, a...) printk(format, ## a)
-#else
-#define DBG_PRINTK(format, a...)
-#endif  
-
-#define TMR_INT_ENABLED_POLL_ACTIVE      0x01
-#define TMR_INT_ENABLED_POLL_CONNECT_ON  0x02
-#define TMR_INT_ENABLED_POLL_CONNECT_OFF 0x04
-#define TMR_INT_ENABLED_POLL_DISCONNECT  0x08
-#define TMR_INT_ENABLED_CMD_EXEC	 0x10
-#define TMR_INT_ENABLED_UPDATE		 0x20
-#define TMR_INT_ENABLED_UDP_PKT		 0x40
-
-#define MAX_X25_ADDR_SIZE	16
-#define MAX_X25_DATA_SIZE 	129
-#define MAX_X25_FACL_SIZE	110
-
-#define TRY_CMD_AGAIN	2
-#define DELAY_RESULT    1
-#define RETURN_RESULT   0
-
-#define DCD(x) (x & 0x03 ? "HIGH" : "LOW")
-#define CTS(x) (x & 0x05 ? "HIGH" : "LOW")
-
-
-/* Driver will not write log messages about 
- * modem status if defined.*/
-#define MODEM_NOT_LOG 1
-
-/*==================================================== 
- * 	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)))
-
-
-/*====================================================
- *           MEMORY DEBUGGING FUNCTION
- *====================================================
-
-#define KMEM_SAFETYZONE 8
-
-static void * dbg_kmalloc(unsigned int size, int prio, int line) {
-	int i = 0;
-	void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio);
-	char * c1 = v;	
-	c1 += sizeof(unsigned int);
-	*((unsigned int *)v) = size;
-
-	for (i = 0; i < KMEM_SAFETYZONE; i++) {
-		c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D';
-		c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F';
-		c1 += 8;
-	}
-	c1 += size;
-	for (i = 0; i < KMEM_SAFETYZONE; i++) {
-		c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G';
-		c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L';
-		c1 += 8;
-	}
-	v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8;
-	printk(KERN_INFO "line %d  kmalloc(%d,%d) = %p\n",line,size,prio,v);
-	return v;
-}
-static void dbg_kfree(void * v, int line) {
-	unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8));
-	unsigned int size = *sp;
-	char * c1 = ((char *)v) - KMEM_SAFETYZONE*8;
-	int i = 0;
-	for (i = 0; i < KMEM_SAFETYZONE; i++) {
-		if (   c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D'
-		    || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') {
-			printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v);
-			printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
-			                c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
-		}
-		c1 += 8;
-	}
-	c1 += size;
-	for (i = 0; i < KMEM_SAFETYZONE; i++) {
-		if (   c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G'
-		    || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L'
-		   ) {
-			printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v);
-			printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
-			                c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
-		}
-		c1 += 8;
-	}
-	printk(KERN_INFO "line %d  kfree(%p)\n",line,v);
-	v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8);
-	kfree(v);
-}
-
-#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)
-#define kfree(x) dbg_kfree(x,__LINE__)
-
-==============================================================*/
-
-
-
-/*===============================================
- * 	Data Structures 
- *===============================================*/
-
-
-/*========================================================
- * Name: 	x25_channel
- *
- * Purpose:	To hold private informaton for each  
- *              logical channel.
- *		
- * Rationale:  	Per-channel debugging is possible if each 
- *              channel has its own private area.
- *	
- * Assumptions:
- *
- * Description:	This is an extention of the struct net_device
- *              we create for each network interface to keep 
- *              the rest of X.25 channel-specific data. 
- *
- * Construct:	Typedef
- */
-typedef struct x25_channel
-{
-	wanpipe_common_t common;	/* common area for x25api and socket */
-	char name[WAN_IFNAME_SZ+1];	/* interface name, ASCIIZ */
-	char addr[WAN_ADDRESS_SZ+1];	/* media address, ASCIIZ */
-	unsigned tx_pkt_size;
-	unsigned short protocol;	/* ethertype, 0 - multiplexed */
-	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 */
-
-	bh_data_t *bh_head;	  	  /* Circular buffer for x25api_bh */
-	unsigned long  tq_working;
-	volatile int  bh_write;
-	volatile int  bh_read;
-	atomic_t  bh_buff_used;
-
-	sdla_t* card;			/* -> owner */
-	struct net_device *dev;		/* -> bound devce */
-
-	int ch_idx;
-	unsigned char enable_IPX;
-	unsigned long network_number;
-	struct net_device_stats ifstats;	/* interface statistics */
-	unsigned short transmit_length;
-	unsigned short tx_offset;
-	char transmit_buffer[X25_CHAN_MTU+sizeof(x25api_hdr_t)];
-
-	if_send_stat_t   if_send_stat;
-        rx_intr_stat_t   rx_intr_stat;
-        pipe_mgmt_stat_t pipe_mgmt_stat;    
-
-	unsigned long router_start_time; /* Router start time in seconds */
-	unsigned long router_up_time;
-	
-} x25_channel_t;
-
-/* FIXME Take this out */
-
-#ifdef NEX_OLD_CALL_INFO
-typedef struct x25_call_info
-{
-	char dest[17];			PACKED;/* ASCIIZ destination address */
-	char src[17];			PACKED;/* ASCIIZ source address */
-	char nuser;			PACKED;/* number of user data bytes */
-	unsigned char user[127];	PACKED;/* user data */
-	char nfacil;			PACKED;/* number of facilities */
-	struct
-	{
-		unsigned char code;     PACKED;
-		unsigned char parm;     PACKED;
-	} facil[64];			        /* facilities */
-} x25_call_info_t;
-#else
-typedef struct x25_call_info
-{
-	char dest[MAX_X25_ADDR_SIZE]		PACKED;/* ASCIIZ destination address */
-	char src[MAX_X25_ADDR_SIZE]		PACKED;/* ASCIIZ source address */
-	unsigned char nuser			PACKED;
-	unsigned char user[MAX_X25_DATA_SIZE]	PACKED;/* user data */
-	unsigned char nfacil			PACKED;
-	unsigned char facil[MAX_X25_FACL_SIZE]	PACKED;
-	unsigned short lcn             		PACKED;
-} x25_call_info_t;
-#endif
-
-
-  
-/*===============================================
- *	Private Function Prototypes
- *==============================================*/
-
-
-/*================================================= 
- * WAN link driver entry points. These are 
- * called by the WAN router module.
- */
-static int update(struct wan_device* wandev);
-static int new_if(struct wan_device* wandev, struct net_device* dev,
-		  wanif_conf_t* conf);
-static int del_if(struct wan_device* wandev, struct net_device* dev);
-static void disable_comm (sdla_t* card);
-static void disable_comm_shutdown(sdla_t *card);
-
-
-
-/*================================================= 
- *	WANPIPE-specific entry points 
- */
-static int wpx_exec (struct sdla* card, void* u_cmd, void* u_data);
-static void x25api_bh(struct net_device *dev);
-static int x25api_bh_cleanup(struct net_device *dev);
-static int bh_enqueue(struct net_device *dev, struct sk_buff *skb);
-
-
-/*=================================================  
- * 	Network device interface 
- */
-static int if_init(struct net_device* dev);
-static int if_open(struct net_device* dev);
-static int if_close(struct net_device* dev);
-static int if_header(struct sk_buff* skb, struct net_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 net_device* dev);
-static struct net_device_stats *if_stats(struct net_device* dev);
-
-static void if_tx_timeout(struct net_device *dev);
-
-/*=================================================  
- * 	Interrupt handlers 
- */
-static void wpx_isr	(sdla_t *);
-static void rx_intr	(sdla_t *);
-static void tx_intr	(sdla_t *);
-static void status_intr	(sdla_t *);
-static void event_intr	(sdla_t *);
-static void spur_intr	(sdla_t *);
-static void timer_intr  (sdla_t *);
-
-static int tx_intr_send(sdla_t *card, struct net_device *dev);
-static struct net_device *move_dev_to_next(sdla_t *card,
-					   struct net_device *dev);
-
-/*=================================================  
- *	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);
-static void trigger_x25_poll(sdla_t *card);
-static void x25_timer_routine(unsigned long data);
-
-
-
-/*=================================================  
- *	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 hdlc_configure (sdla_t* card, TX25Config* conf);
-static int set_hdlc_level (sdla_t* card);
-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 net_device* get_dev_by_lcn(struct wan_device* wandev,
-					 unsigned lcn);
-static int chan_connect(struct net_device* dev);
-static int chan_disc(struct net_device* dev);
-static void set_chan_state(struct net_device* dev, int state);
-static int chan_send(struct net_device *dev, void* buff, unsigned data_len,
-		     unsigned char tx_intr);
-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*, int);
-static void parse_call_info (unsigned char*, x25_call_info_t*);
-static struct net_device *find_channel(sdla_t *card, unsigned lcn);
-static void bind_lcn_to_dev(sdla_t *card, struct net_device *dev, unsigned lcn);
-static void setup_for_delayed_transmit(struct net_device *dev,
-				       void *buf, unsigned len);
-
-
-/*=================================================  
- *      X25 API Functions 
- */
-static int wanpipe_pull_data_in_skb(sdla_t *card, struct net_device *dev,
-				    struct sk_buff **);
-static void timer_intr_exec(sdla_t *, unsigned char);
-static int execute_delayed_cmd(sdla_t *card, struct net_device *dev,
-			       mbox_cmd_t *usr_cmd, char bad_cmd);
-static int api_incoming_call (sdla_t*, TX25Mbox *, int);
-static int alloc_and_init_skb_buf (sdla_t *,struct sk_buff **, int);
-static void send_delayed_cmd_result(sdla_t *card, struct net_device *dev,
-				    TX25Mbox* mbox);
-static int clear_confirm_event (sdla_t *, TX25Mbox*);
-static void send_oob_msg (sdla_t *card, struct net_device *dev, TX25Mbox *mbox);
-static int timer_intr_cmd_exec(sdla_t *card);
-static void api_oob_event (sdla_t *card,TX25Mbox *mbox);
-static int check_bad_command(sdla_t *card, struct net_device *dev);
-static int channel_disconnect(sdla_t* card, struct net_device *dev);
-static void hdlc_link_down (sdla_t*);
-
-/*=================================================
- *     XPIPEMON Functions
- */
-static int process_udp_mgmt_pkt(sdla_t *);
-static int udp_pkt_type( struct sk_buff *, sdla_t*);
-static int reply_udp( unsigned char *, unsigned int); 
-static void init_x25_channel_struct( x25_channel_t *);
-static void init_global_statistics( sdla_t *);
-static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t *card,
-			      struct net_device *dev,
-			      struct sk_buff *skb, int lcn);
-static unsigned short calc_checksum (char *, int);
-
-
-
-/*================================================= 
- *	IPX functions 
- */
-static void switch_net_numbers(unsigned char *, unsigned long, unsigned char);
-static int handle_IPXWAN(unsigned char *, char *, unsigned char , 
-			 unsigned long , unsigned short );
-
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-static void S508_S514_lock(sdla_t *, unsigned long *);
-static void S508_S514_unlock(sdla_t *, unsigned long *);
-
-
-/*=================================================  
- * 	Global Variables 
- *=================================================*/
-
-
-
-/*================================================= 
- *	Public Functions 
- *=================================================*/
-
-
-
-
-/*===================================================================
- * wpx_init:	X.25 Protocol Initialization routine.
- *
- * Purpose:	To initialize the protocol/firmware.
- * 
- * Rationale:	This function is called by setup() function, in
- *              sdlamain.c, to dynamically setup the x25 protocol.
- *		This is the first protocol specific function, which
- *              executes once on startup.
- *                
- * Description:	This procedure initializes the x25 firmware and
- *    		sets up the mailbox, transmit and receive buffer
- *              pointers. It also initializes all debugging structures
- *              and sets up the X25 environment.
- *
- *		Sets up hardware options defined by user in [wanpipe#] 
- *		section of wanpipe#.conf configuration file. 
- *
- * 		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.
- *
- * Called by:	setup() function in sdlamain.c
- *
- * Assumptions:	None
- *
- * Warnings:	None
- *
- * 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);
-
-	/* Initialize for S514 Card */
-	if(card->hw.type == SDLA_S514) {
-		card->mbox += X25_MB_VECTOR;
-		card->flags += X25_MB_VECTOR;
-		card->rxmb += X25_MB_VECTOR;
-	}
-
-
-	/* 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;
-
-
-	/* X25 firmware can run ether in X25 or LAPB HDLC mode.
-         * Check the user defined option and configure accordingly */
-	if (conf->u.x25.LAPB_hdlc_only == WANOPT_YES){
-		if (set_hdlc_level(card) != CMD_OK){
-			return -EIO;	
-		}else{
-			printk(KERN_INFO "%s: running LAP_B HDLC firmware v%s\n",
-				card->devname, u.str);
-		}
-		card->u.x.LAPB_hdlc = 1;
-	}else{
-		printk(KERN_INFO "%s: running X.25 firmware v%s\n",
-				card->devname, u.str);
-		card->u.x.LAPB_hdlc = 0;
-	}
-
-	/* 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.
-	 */
-	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		= 0x0090;	/* 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 (card->u.x.LAPB_hdlc){
-		u.cfg.hdlcMTU = 1027;
-	}
-
-	if (conf->u.x25.x25_conf_opt){
-		u.cfg.options = conf->u.x25.x25_conf_opt;
-	}
-
-	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_t(unsigned int, conf->u.x25.hi_pvc, MAX_LCN_NUM);
-		card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
-	}
-
-	if (conf->u.x25.hi_svc){
-		card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, MAX_LCN_NUM);
-		card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
-	}
-
-	/* Figure out the total number of channels to configure */
-	card->u.x.num_of_ch = 0;
-	if (card->u.x.hi_svc != 0){
-		card->u.x.num_of_ch = (card->u.x.hi_svc - card->u.x.lo_svc) + 1;
-	}
-	if (card->u.x.hi_pvc != 0){
-		card->u.x.num_of_ch += (card->u.x.hi_pvc - card->u.x.lo_pvc) + 1;
-	}
-
-	if (card->u.x.num_of_ch == 0){
-		printk(KERN_INFO "%s: ERROR, Minimum number of PVC/SVC channels is 1 !\n"
-				 "%s: Please set the Lowest/Highest PVC/SVC values !\n",
-				 card->devname,card->devname);
-		return -ECHRNG;
-	}
-	
-	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_t(unsigned int, conf->u.x25.hdlc_window, 7);
-	if (conf->u.x25.pkt_window)
-		u.cfg.pktWindow = min_t(unsigned int, conf->u.x25.pkt_window, 7);
-
-	if (conf->u.x25.t1)
-		u.cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
-	if (conf->u.x25.t2)
-		u.cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 29);
-	if (conf->u.x25.t4)
-		u.cfg.t4 = min_t(unsigned int, conf->u.x25.t4, 240);
-	if (conf->u.x25.n2)
-		u.cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
-
-	if (conf->u.x25.t10_t20)
-		u.cfg.t10t20 = min_t(unsigned int, conf->u.x25.t10_t20,255);
-	if (conf->u.x25.t11_t21)
-		u.cfg.t11t21 = min_t(unsigned int, conf->u.x25.t11_t21,255);
-	if (conf->u.x25.t12_t22)
-		u.cfg.t12t22 = min_t(unsigned int, conf->u.x25.t12_t22,255);
-	if (conf->u.x25.t13_t23)	
-		u.cfg.t13t23 = min_t(unsigned int, conf->u.x25.t13_t23,255);
-	if (conf->u.x25.t16_t26)
-		u.cfg.t16t26 = min_t(unsigned int, conf->u.x25.t16_t26, 255);
-	if (conf->u.x25.t28)
-		u.cfg.t28 = min_t(unsigned int, conf->u.x25.t28, 255);
-
-	if (conf->u.x25.r10_r20)
-		u.cfg.r10r20 = min_t(unsigned int, conf->u.x25.r10_r20,250);
-	if (conf->u.x25.r12_r22)
-		u.cfg.r12r22 = min_t(unsigned int, conf->u.x25.r12_r22,250);
-	if (conf->u.x25.r13_r23)
-		u.cfg.r13r23 = min_t(unsigned int, conf->u.x25.r13_r23,250);
-
-
-	if (conf->u.x25.ccitt_compat)
-		u.cfg.ccittCompat = conf->u.x25.ccitt_compat;
-
-	/* initialize adapter */
-	if (card->u.x.LAPB_hdlc){
-		if (hdlc_configure(card, &u.cfg) != CMD_OK)
-			return -EIO;
-	}else{
-		if (x25_configure(card, &u.cfg) != CMD_OK)
-			return -EIO;
-	}
-
-	if ((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		= NULL; //&wpx_poll;
-	card->disable_comm	= &disable_comm;
-	card->exec		= &wpx_exec;
-	card->wandev.update	= &update;
-	card->wandev.new_if	= &new_if;
-	card->wandev.del_if	= &del_if;
-
-	/* WARNING: This function cannot exit with an error
-	 *          after the change of state */
-	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->u.x.tx_dev = NULL;
-	card->u.x.no_dev = 0;
-
-
-	/* Configure for S514 PCI Card */
-	if (card->hw.type == SDLA_S514) {
-		card->u.x.hdlc_buf_status = 
-			(volatile unsigned char *)
-				(card->hw.dpmbase + X25_MB_VECTOR+ X25_MISC_HDLC_BITS);
-	}else{
-		card->u.x.hdlc_buf_status = 
-			(volatile unsigned char *)(card->hw.dpmbase + X25_MISC_HDLC_BITS); 
-	}
-
-	card->u.x.poll_device=NULL;
-	card->wandev.udp_port = conf->udp_port;
-
-	/* Enable or disable call setup logging */
-	if (conf->u.x25.logging == WANOPT_YES){
-		printk(KERN_INFO "%s: Enabling Call Logging.\n",
-			card->devname);
-		card->u.x.logging = 1;
-	}else{	
-		card->u.x.logging = 0;
-	}
-
-	/* Enable or disable modem status reporting */
-	if (conf->u.x25.oob_on_modem == WANOPT_YES){
-		printk(KERN_INFO "%s: Enabling OOB on Modem change.\n",
-			card->devname);
-		card->u.x.oob_on_modem = 1;
-	}else{
-		card->u.x.oob_on_modem = 0;
-	}
-	
-	init_global_statistics(card);	
-
-	INIT_WORK(&card->u.x.x25_poll_work, (void *)wpx_poll, card);
-
-	init_timer(&card->u.x.x25_timer);
-	card->u.x.x25_timer.data = (unsigned long)card;
-	card->u.x.x25_timer.function = x25_timer_routine;
-	
-	return 0;
-}
-
-/*=========================================================
- *	WAN Device Driver Entry Points 
- *========================================================*/
-
-/*============================================================
- * Name:	update(),  Update device status & statistics.
- *
- * Purpose:	To provide debugging and statitical
- *              information to the /proc file system.
- *              /proc/net/wanrouter/wanpipe#
- *              	
- * Rationale:	The /proc file system is used to collect
- *              information about the kernel and drivers.
- *              Using the /proc file system the user
- *              can see exactly what the sangoma drivers are
- *              doing. And in what state they are in. 
- *                
- * Description: Collect all driver statistical information
- *              and pass it to the top laywer. 
- *		
- *		Since we have to execute a debugging command, 
- *              to obtain firmware statitics, we trigger a 
- *              UPDATE function within the timer interrtup.
- *              We wait until the timer update is complete.
- *              Once complete return the appropriate return
- *              code to indicate that the update was successful.
- *              
- * Called by:	device_stat() in wanmain.c
- *
- * Assumptions:	
- *
- * Warnings:	This function will degrade the performance
- *              of the router, since it uses the mailbox. 
- *
- * Return: 	0 	OK
- * 		<0	Failed (or busy).
- */
-
-static int update(struct wan_device* wandev)
-{
-	volatile sdla_t* card;
-	TX25Status* status;
-	unsigned long timeout;
-
-	/* sanity checks */
-	if ((wandev == NULL) || (wandev->private == NULL))
-		return -EFAULT;
-
-	if (wandev->state == WAN_UNCONFIGURED)
-		return -ENODEV;
-
-	if (test_bit(SEND_CRIT, (void*)&wandev->critical))
-		return -EAGAIN;
-
-	if (!wandev->dev)
-		return -ENODEV;
-	
-	card = wandev->private;
-	status = card->flags;
-
-	card->u.x.timer_int_enabled |= TMR_INT_ENABLED_UPDATE;
-	status->imask |= INTR_ON_TIMER;
-	timeout = jiffies;	
-
-	for (;;){
-		if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_UPDATE)){	
-			break;
-		}
-		if (time_after(jiffies, timeout + 1*HZ)){
-			card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE;
-			return -EAGAIN;
-		}
-	}
-	return 0;
-}
-
-
-/*===================================================================
- * 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;
-}
-
-/*======================================================================
- * 	Build media header.
- * 	o encapsulate packet according to encapsulation type.
- *
- * 	The trick here is to put packet type (Ethertype) into 'protocol' 
- *      field of the socket buffer, so that we don't forget it.  
- *      If encapsulation fails, set skb->protocol to 0 and discard 
- *      packet later.
- *
- * 	Return:		media header length.
- *======================================================================*/
-
-static int if_header(struct sk_buff* skb, struct net_device* dev,
-		     unsigned short type, void* daddr, void* saddr,
-		     unsigned len)
-{
-	x25_channel_t* chan = dev->priv;
-	int hdr_len = dev->hard_header_len;
-	
-	skb->protocol = htons(type);
-	if (!chan->protocol){
-		hdr_len = wanrouter_encapsulate(skb, dev, type);
-		if (hdr_len < 0){
-			hdr_len = 0;
-			skb->protocol = htons(0);
-		}
-	}
-	return hdr_len;
-}
-
-/*===============================================================
- * 	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; 
-	x25_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)
-{
-    	x25_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->if_send_stat.if_send_tbusy_timeout;
-	printk (KERN_INFO "%s: Transmit timed out on %s\n", 
-			card->devname, dev->name);
-	netif_wake_queue (dev);
-}
-
-
-/*=========================================================================
- * 	Send a packet on a network interface.
- * 	o set tbusy flag (marks start of the transmission).
- * 	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)
- *		non-0	packet may be re-transmitted (tbusy must be set)
- *
- * 	Notes:
- * 	1. This routine is called either by the protocol stack or by the "net
- *    	bottom half" (with interrupts enabled).
- * 	2. Setting tbusy flag will inhibit further transmit requests from the
- *    	protocol stack and can be used for flow control with protocol layer.
- *
- *========================================================================*/
-
-static int if_send(struct sk_buff* skb, struct net_device* dev)
-{
-	x25_channel_t* chan = dev->priv;
-	sdla_t* card = chan->card;
-	TX25Status* status = card->flags;
-	int udp_type;
-	unsigned long smp_flags=0;
-
-	++chan->if_send_stat.if_send_entry;
-
-	netif_stop_queue(dev);
-
-	/* No need to check frame length, since socket code
-         * will perform the check for us */
-
-	chan->tick_counter = jiffies;
-	
-	/* Critical region starts here */
-	S508_S514_lock(card, &smp_flags);
-	
-	if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)){
-		printk(KERN_INFO "Hit critical in if_send()! %lx\n",card->wandev.critical);
-		goto if_send_crit_exit;
-	}
-	
-	udp_type = udp_pkt_type(skb, card);
-
-        if(udp_type != UDP_INVALID_TYPE) {
-
-                if(store_udp_mgmt_pkt(udp_type, UDP_PKT_FRM_STACK, card, dev, skb,
-                        chan->common.lcn)) {
-
-                        status->imask |= INTR_ON_TIMER;
-                        if (udp_type == UDP_XPIPE_TYPE){
-                                chan->if_send_stat.if_send_PIPE_request++;
-			}
-               	}
-		netif_start_queue(dev);
-		clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
-		S508_S514_unlock(card, &smp_flags);
-		return 0;
-	}
-
-	if (chan->transmit_length){
-		//FIXME: This check doesn't make sense any more
-		if (chan->common.state != WAN_CONNECTED){
-			chan->transmit_length=0;
-			atomic_set(&chan->common.driver_busy,0);
-		}else{
-			netif_stop_queue(dev);
-			++card->u.x.tx_interrupts_pending;
-		        status->imask |= INTR_ON_TX_FRAME;
-			clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
-			S508_S514_unlock(card, &smp_flags);
-			return 1;
-		}
-	}
-
-	if (card->wandev.state != WAN_CONNECTED){
-		++chan->ifstats.tx_dropped;
-		++card->wandev.stats.tx_dropped;
-		++chan->if_send_stat.if_send_wan_disconnected;	
-		
-	}else if ( chan->protocol && (chan->protocol != skb->protocol)){
-		printk(KERN_INFO
-			"%s: unsupported Ethertype 0x%04X on interface %s!\n",
-			chan->name, htons(skb->protocol), dev->name);
-		
-		printk(KERN_INFO "PROTO %Xn", htons(chan->protocol));
-		++chan->ifstats.tx_errors;
-		++chan->ifstats.tx_dropped;
-		++card->wandev.stats.tx_dropped;
-		++chan->if_send_stat.if_send_protocol_error;
-		
-	}else switch (chan->common.state){
-
-		case WAN_DISCONNECTED:
-			/* Try to establish connection. If succeded, then start
-			 * transmission, else drop a packet.
-			 */
-			if (chan->common.usedby == API){
-				++chan->ifstats.tx_dropped;
-				++card->wandev.stats.tx_dropped;
-				break;
-			}else{
-				if (chan_connect(dev) != 0){
-					++chan->ifstats.tx_dropped;
-					++card->wandev.stats.tx_dropped;
-					break;
-				}
-			}
-			/* fall through */
-
-		case WAN_CONNECTED:
-			if( skb->protocol == htons(ETH_P_IPX)) {
-				if(chan->enable_IPX) {
-					switch_net_numbers( skb->data, 
-						chan->network_number, 0);
-				} else {
-					++card->wandev.stats.tx_dropped;
-					++chan->ifstats.tx_dropped;
-					++chan->if_send_stat.if_send_protocol_error;
-					goto if_send_crit_exit;
-				}
-			}
-			/* We never drop here, if cannot send than, copy
-	                 * a packet into a transmit buffer 
-                         */
-			chan_send(dev, skb->data, skb->len, 0);
-			break;
-
-		default:
-			++chan->ifstats.tx_dropped;	
-			++card->wandev.stats.tx_dropped;
-			break;
-	}
-
-
-if_send_crit_exit:
-	
-       	dev_kfree_skb_any(skb);
-
-	netif_start_queue(dev);
-	clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
-	S508_S514_unlock(card, &smp_flags);
-	return 0;
-}
-
-/*============================================================================
- * Setup so that a frame can be transmitted on the occurrence of a transmit
- * interrupt.
- *===========================================================================*/
-
-static void setup_for_delayed_transmit(struct net_device* dev, void* buf,
-				       unsigned len)
-{
-        x25_channel_t* chan = dev->priv;
-        sdla_t* card = chan->card;
-	TX25Status* status = card->flags;
-
-	++chan->if_send_stat.if_send_adptr_bfrs_full;
-
-        if(chan->transmit_length) {
-                printk(KERN_INFO "%s: Error, transmit length set in delayed transmit!\n",
-				card->devname);
-                return;
-        }
-
-	if (chan->common.usedby == API){
-		if (len > X25_CHAN_MTU+sizeof(x25api_hdr_t)) {
-			++chan->ifstats.tx_dropped;	
-			++card->wandev.stats.tx_dropped;
-			printk(KERN_INFO "%s: Length is too big for delayed transmit\n",
-				card->devname);
-			return;
-		}
-	}else{
-		if (len > X25_MAX_DATA) {
-			++chan->ifstats.tx_dropped;	
-			++card->wandev.stats.tx_dropped;
-			printk(KERN_INFO "%s: Length is too big for delayed transmit\n",
-				card->devname);
-			return;
-		}
-	}
-
-        chan->transmit_length = len;
-	atomic_set(&chan->common.driver_busy,1);
-        memcpy(chan->transmit_buffer, buf, len);
-
-	++chan->if_send_stat.if_send_tx_int_enabled;
-
-	/* Enable Transmit Interrupt */
-	++card->u.x.tx_interrupts_pending;
-        status->imask |= INTR_ON_TX_FRAME;
-}
-
-
-/*===============================================================
- * net_device_stats
- *
- * 	Get ethernet-style interface statistics.
- * 	Return a pointer to struct enet_statistics.
- *
- *==============================================================*/
-static struct net_device_stats *if_stats(struct net_device* dev)
-{
-	x25_channel_t *chan = dev->priv;
-
-	if(chan == NULL)
-		return NULL;
-
-	return &chan->ifstats;
-}
-
-
-/*
- *	Interrupt Handlers 
- */
-
-/*
- * X.25 Interrupt Service Routine.
- */
-
-static void wpx_isr (sdla_t* card)
-{
-	TX25Status* status = card->flags;
-
-	card->in_isr = 1;
-	++card->statistics.isr_entry;
-
-	if (test_bit(PERI_CRIT,(void*)&card->wandev.critical)){
-		card->in_isr=0;
-		status->iflags = 0;
-		return;
-	}
-	
-	if (test_bit(SEND_CRIT, (void*)&card->wandev.critical)){
-
- 		printk(KERN_INFO "%s: wpx_isr: wandev.critical set to 0x%02lx, int type = 0x%02x\n", 
-			card->devname, card->wandev.critical, status->iflags);
-		card->in_isr = 0;
-		status->iflags = 0;
-		return;
-	}
-
-	/* For all interrupts set the critical flag to CRITICAL_RX_INTR.
-         * If the if_send routine is called with this flag set it will set
-         * the enable transmit flag to 1. (for a delayed interrupt)
-         */
-	switch (status->iflags){
-
-		case RX_INTR_PENDING:		/* receive interrupt */
-			rx_intr(card);
-			break;
-
-		case TX_INTR_PENDING:		/* transmit interrupt */
-			tx_intr(card);
-			break;
-
-		case MODEM_INTR_PENDING:	/* modem status interrupt */
-			status_intr(card);
-			break;
-
-		case X25_ASY_TRANS_INTR_PENDING:	/* network event interrupt */
-			event_intr(card);
-			break;
-
-		case TIMER_INTR_PENDING:
-			timer_intr(card);
-			break;
-
-		default:		/* unwanted interrupt */
-			spur_intr(card);
-	}
-
-	card->in_isr = 0;
-	status->iflags = 0;	/* clear interrupt condition */
-}
-
-/*
- * 	Receive interrupt handler.
- * 	This routine handles fragmented IP packets using M-bit according to the
- * 	RFC1356.
- * 	o map ligical channel number to network interface.
- * 	o allocate socket buffer or append received packet to the existing one.
- * 	o if M-bit is reset (i.e. it's the last packet in a sequence) then 
- *   	decapsulate packet and pass socket buffer to the protocol stack.
- *
- * 	Notes:
- * 	1. When allocating a socket buffer, if M-bit is set then more data is
- *    	coming and we have to allocate buffer for the maximum IP packet size
- *    	expected on this channel.
- * 	2. If something goes wrong and X.25 packet has to be dropped (e.g. no
- *    	socket buffers available) the whole packet sequence must be discarded.
- */
-
-static void rx_intr (sdla_t* card)
-{
-	TX25Mbox* rxmb = card->rxmb;
-	unsigned lcn = rxmb->cmd.lcn;
-	struct net_device* dev = find_channel(card,lcn);
-	x25_channel_t* chan;
-	struct sk_buff* skb=NULL;
-
-	if (dev == NULL){
-		/* Invalid channel, discard packet */
-		printk(KERN_INFO "%s: receiving on orphaned LCN %d!\n",
-			card->devname, lcn);
-		return;
-	}
-
-	chan = dev->priv;
-	chan->i_timeout_sofar = jiffies;
-
-
-	/* Copy the data from the board, into an
-         * skb buffer 
-	 */
-	if (wanpipe_pull_data_in_skb(card,dev,&skb)){
-		++chan->ifstats.rx_dropped;
-		++card->wandev.stats.rx_dropped;
-		++chan->rx_intr_stat.rx_intr_no_socket;
-		++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack;
-		return;
-	}
-
-	dev->last_rx = jiffies;		/* timestamp */
-
-
-	/* ------------ API ----------------*/
-
-	if (chan->common.usedby == API){
-
-		if (bh_enqueue(dev, skb)){
-			++chan->ifstats.rx_dropped;
-			++card->wandev.stats.rx_dropped;
-			++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack;
-			dev_kfree_skb_any(skb);
-			return;
-		}		
-
-		++chan->ifstats.rx_packets;
-		chan->ifstats.rx_bytes += skb->len;
-		
-
-		chan->rx_skb = NULL;
-		if (!test_and_set_bit(0, &chan->tq_working)){
-			wanpipe_queue_work(&chan->common.wanpipe_work);
-		}
-		return;
-	}
-
-
-	/* ------------- WANPIPE -------------------*/
-	
-	/* set rx_skb to NULL so we won't access it later when kernel already owns it */
-	chan->rx_skb=NULL;
-	
-	/* Decapsulate packet, if necessary */
-	if (!skb->protocol && !wanrouter_type_trans(skb, dev)){
-		/* can't decapsulate packet */
-                dev_kfree_skb_any(skb);
-		++chan->ifstats.rx_errors;
-		++chan->ifstats.rx_dropped;
-		++card->wandev.stats.rx_dropped;
-		++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack;
-
-	}else{
-		if( handle_IPXWAN(skb->data, chan->name, 
-				  chan->enable_IPX, chan->network_number, 
-				  skb->protocol)){
-
-			if( chan->enable_IPX ){
-				if(chan_send(dev, skb->data, skb->len,0)){
-					chan->tx_skb = skb;
-				}else{
-                                        dev_kfree_skb_any(skb);
-					++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack;
-				}
-			}else{
-				/* increment IPX packet dropped statistic */
-				++chan->ifstats.rx_dropped;
-				++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack;
-			}
-		}else{
-			skb->mac.raw = skb->data;
-			chan->ifstats.rx_bytes += skb->len;
-			++chan->ifstats.rx_packets;
-			++chan->rx_intr_stat.rx_intr_bfr_passed_to_stack;
-			netif_rx(skb);
-		}
-	}
-	
-	return;
-}
-
-
-static int wanpipe_pull_data_in_skb(sdla_t *card, struct net_device *dev,
-				    struct sk_buff **skb)
-{
-	void *bufptr;
-	TX25Mbox* rxmb = card->rxmb;
-	unsigned len = rxmb->cmd.length;	/* packet length */
-	unsigned qdm = rxmb->cmd.qdm;		/* Q,D and M bits */
-	x25_channel_t *chan = dev->priv;
-	struct sk_buff *new_skb = *skb;
-
-	if (chan->common.usedby == WANPIPE){
-		if (chan->drop_sequence){
-			if (!(qdm & 0x01)){ 
-				chan->drop_sequence = 0;
-			}
-			return 1;
-		}
-		new_skb = chan->rx_skb;
-	}else{
-		/* Add on the API header to the received
-                 * data 
-		 */
-		len += sizeof(x25api_hdr_t);
-	}
-
-	if (new_skb == NULL){
-		int bufsize;
-
-		if (chan->common.usedby == WANPIPE){
-			bufsize = (qdm & 0x01) ? dev->mtu : len;
-		}else{
-			bufsize = len;
-		}
-
-		/* Allocate new socket buffer */
-		new_skb = dev_alloc_skb(bufsize + dev->hard_header_len);
-		if (new_skb == NULL){
-			printk(KERN_INFO "%s: no socket buffers available!\n",
-				card->devname);
-			chan->drop_sequence = 1;	/* set flag */
-			++chan->ifstats.rx_dropped;
-			return 1;
-		}
-	}
-
-	if (skb_tailroom(new_skb) < len){
-		/* No room for the packet. Call off the whole thing! */
-                dev_kfree_skb_any(new_skb);
-		if (chan->common.usedby == WANPIPE){
-			chan->rx_skb = NULL;
-			if (qdm & 0x01){ 
-				chan->drop_sequence = 1;
-			}
-		}
-
-		printk(KERN_INFO "%s: unexpectedly long packet sequence "
-			"on interface %s!\n", card->devname, dev->name);
-		++chan->ifstats.rx_length_errors;
-		return 1;
-	}
-
-	bufptr = skb_put(new_skb,len);
-
-
-	if (chan->common.usedby == API){
-		/* Fill in the x25api header 
-		 */
-		x25api_t * api_data = (x25api_t*)bufptr;
-		api_data->hdr.qdm = rxmb->cmd.qdm;
-		api_data->hdr.cause = rxmb->cmd.cause;
-		api_data->hdr.diagn = rxmb->cmd.diagn;
-		api_data->hdr.length = rxmb->cmd.length;
-		memcpy(api_data->data, rxmb->data, rxmb->cmd.length);
-	}else{
-		memcpy(bufptr, rxmb->data, len);
-	}
-
-	new_skb->dev = dev;
-
-	if (chan->common.usedby == API){
-		new_skb->mac.raw = new_skb->data;
-		new_skb->protocol = htons(X25_PROT);
-		new_skb->pkt_type = WAN_PACKET_DATA;
-	}else{
-		new_skb->protocol = chan->protocol;
-		chan->rx_skb = new_skb;
-	}
-
-	/* If qdm bit is set, more data is coming 
-         * thus, exit and wait for more data before
-         * sending the packet up. (Used by router only) 
-	 */
-	if ((qdm & 0x01) && (chan->common.usedby == WANPIPE)) 
-		return 1;	
-
-	*skb = new_skb; 
-
-	return 0;
-}
-
-/*===============================================================
- * tx_intr
- *  
- * 	Transmit interrupt handler.
- *	For each dev, check that there is something to send.
- *	If data available, transmit. 	
- *
- *===============================================================*/
-
-static void tx_intr (sdla_t* card)
-{
-	struct net_device *dev;
-	TX25Status* status = card->flags;
-	unsigned char more_to_tx=0;
-	x25_channel_t *chan=NULL;
-	int i=0;	
-
-	if (card->u.x.tx_dev == NULL){
-		card->u.x.tx_dev = card->wandev.dev;
-	}
-
-	dev = card->u.x.tx_dev;
-
-	for (;;){
-
-		chan = dev->priv;
-		if (chan->transmit_length){
-			/* Device was set to transmit, check if the TX
-                         * buffers are available 
-			 */		
-			if (chan->common.state != WAN_CONNECTED){
-				chan->transmit_length = 0;
-				atomic_set(&chan->common.driver_busy,0);
-				chan->tx_offset=0;
-				if (netif_queue_stopped(dev)){
-					if (chan->common.usedby == API){
-						netif_start_queue(dev);
-						wakeup_sk_bh(dev);
-					}else{
-						netif_wake_queue(dev);
-					}
-				}
-				dev = move_dev_to_next(card,dev);
-				break;
-			}				
-
-			if ((status->cflags[chan->ch_idx] & 0x40 || card->u.x.LAPB_hdlc) && 
-			     (*card->u.x.hdlc_buf_status & 0x40) ){
-				/* Tx buffer available, we can send */
-				
-				if (tx_intr_send(card, dev)){
-					more_to_tx=1;
-				}
-
-				/* If more than one interface present, move the
-                                 * device pointer to the next interface, so on the 
-                                 * next TX interrupt we will try sending from it. 
-                                 */
-				dev = move_dev_to_next(card,dev);
-				break;
-			}else{
-				/* Tx buffers not available, but device set
-                                 * the TX interrupt.  Set more_to_tx and try  
-                                 * to transmit for other devices.
-				 */
-				more_to_tx=1;
-				dev = move_dev_to_next(card,dev);
-			}
-
-		}else{
-			/* This device was not set to transmit,
-                         * go to next 
-			 */
-			dev = move_dev_to_next(card,dev);
-		}	
-
-		if (++i == card->u.x.no_dev){
-			if (!more_to_tx){
-				DBG_PRINTK(KERN_INFO "%s: Nothing to Send in TX INTR\n",
-					card->devname);
-			}
-			break;
-		}
-
-	} //End of FOR
-
-	card->u.x.tx_dev = dev;
-	
-	if (!more_to_tx){
-		/* if any other interfaces have transmit interrupts pending, */
-		/* do not disable the global transmit interrupt */
-		if (!(--card->u.x.tx_interrupts_pending)){
-			status->imask &= ~INTR_ON_TX_FRAME;
-		}
-	}
-	return;
-}
-
-/*===============================================================
- * move_dev_to_next
- *  
- *
- *===============================================================*/
-
-
-struct net_device *move_dev_to_next(sdla_t *card, struct net_device *dev)
-{
-	if (card->u.x.no_dev != 1){
-		if (!*((struct net_device **)dev->priv))
-			return card->wandev.dev;
-		else
-			return *((struct net_device **)dev->priv);
-	}
-	return dev;
-}
-
-/*===============================================================
- *  tx_intr_send
- *  
- *
- *===============================================================*/
-
-static int tx_intr_send(sdla_t *card, struct net_device *dev)
-{
-	x25_channel_t* chan = dev->priv; 
-
-	if (chan_send (dev,chan->transmit_buffer,chan->transmit_length,1)){
-		 
-                /* Packet was split up due to its size, do not disable
-                 * tx_intr 
-                 */
-		return 1;
-	}
-
-	chan->transmit_length=0;
-	atomic_set(&chan->common.driver_busy,0);
-	chan->tx_offset=0;
-
-	/* If we are in API mode, wakeup the 
-         * sock BH handler, not the NET_BH */
-	if (netif_queue_stopped(dev)){
-		if (chan->common.usedby == API){
-			netif_start_queue(dev);
-			wakeup_sk_bh(dev);
-		}else{
-			netif_wake_queue(dev);
-		}
-	}
-	return 0;
-}
-
-
-/*===============================================================
- * timer_intr
- *  
- * 	Timer interrupt handler.
- *	Check who called the timer interrupt and perform
- *      action accordingly.
- *
- *===============================================================*/
-
-static void timer_intr (sdla_t *card)
-{
-	TX25Status* status = card->flags;
-
-	if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_CMD_EXEC){
-
-		if (timer_intr_cmd_exec(card) == 0){
-			card->u.x.timer_int_enabled &=
-				~TMR_INT_ENABLED_CMD_EXEC;
-		}
-
-	}else  if(card->u.x.timer_int_enabled & TMR_INT_ENABLED_UDP_PKT) {
-
-		if ((*card->u.x.hdlc_buf_status & 0x40) && 
-		    card->u.x.udp_type == UDP_XPIPE_TYPE){
-
-                    	if(process_udp_mgmt_pkt(card)) {
-		                card->u.x.timer_int_enabled &= 
-					~TMR_INT_ENABLED_UDP_PKT;
-			}
-		}
-
-	}else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_POLL_ACTIVE) {
-
-		struct net_device *dev = card->u.x.poll_device;
-		x25_channel_t *chan = NULL;
-
-		if (!dev){
-			card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_ACTIVE;
-			return;
-		}
-		chan = dev->priv;
-
-		printk(KERN_INFO 
-			"%s: Closing down Idle link %s on LCN %d\n",
-					card->devname,chan->name,chan->common.lcn); 
-		chan->i_timeout_sofar = jiffies;
-		chan_disc(dev);	
-         	card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_ACTIVE;
-		card->u.x.poll_device=NULL;
-
-	}else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_POLL_CONNECT_ON) {
-
-		wanpipe_set_state(card, WAN_CONNECTED);
-		if (card->u.x.LAPB_hdlc){
-			struct net_device *dev = card->wandev.dev;
-			set_chan_state(dev,WAN_CONNECTED);
-			send_delayed_cmd_result(card,dev,card->mbox);	
-		}
-
-		/* 0x8F enable all interrupts */
-		x25_set_intr_mode(card, INTR_ON_RX_FRAME|	
-					INTR_ON_TX_FRAME|
-					INTR_ON_MODEM_STATUS_CHANGE|
-					//INTR_ON_COMMAND_COMPLETE|
-					X25_ASY_TRANS_INTR_PENDING |
-					INTR_ON_TIMER |
-					DIRECT_RX_INTR_USAGE
-				); 
-
-		status->imask &= ~INTR_ON_TX_FRAME;	/* mask Tx interrupts */
-		card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_CONNECT_ON;
-
-	}else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_POLL_CONNECT_OFF) {
-
-		//printk(KERN_INFO "Poll connect, Turning OFF\n");
-		disconnect(card);
-		card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_CONNECT_OFF;
-
-	}else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_POLL_DISCONNECT) {
-
-		//printk(KERN_INFO "POll disconnect, trying to connect\n");
-		connect(card);
-		card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_POLL_DISCONNECT;
-
-	}else if (card->u.x.timer_int_enabled & TMR_INT_ENABLED_UPDATE){
-
-		if (*card->u.x.hdlc_buf_status & 0x40){
-			x25_get_err_stats(card);
-			x25_get_stats(card);
-			card->u.x.timer_int_enabled &= ~TMR_INT_ENABLED_UPDATE;
-		}
-	}
-
-	if(!card->u.x.timer_int_enabled){
-		//printk(KERN_INFO "Turning Timer Off \n");
-                status->imask &= ~INTR_ON_TIMER;	
-	}
-}
-
-/*====================================================================
- * 	Modem status interrupt handler.
- *===================================================================*/
-static void status_intr (sdla_t* card)
-{
-
-	/* Added to avoid Modem status message flooding */
-	static TX25ModemStatus last_stat;
-
-	TX25Mbox* mbox = card->mbox;
-	TX25ModemStatus *modem_status;
-	struct net_device *dev;
-	x25_channel_t *chan;
-	int err;
-
-	memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-	mbox->cmd.command = X25_READ_MODEM_STATUS;
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	if (err){ 
-		x25_error(card, err, X25_READ_MODEM_STATUS, 0);
-	}else{
-	
-		modem_status = (TX25ModemStatus*)mbox->data;	
-	
-           	/* Check if the last status was the same
-           	 * if it was, do NOT print message again */
-	
-		if (last_stat.status != modem_status->status){
-
-	     		printk(KERN_INFO "%s: Modem Status Change: DCD=%s, CTS=%s\n",
-				card->devname,DCD(modem_status->status),CTS(modem_status->status));
-
-			last_stat.status = modem_status->status;
-		
-			if (card->u.x.oob_on_modem){
-
-				mbox->cmd.pktType = mbox->cmd.command;
-				mbox->cmd.result = 0x08;
-
-				/* Send a OOB to all connected sockets */
-				for (dev = card->wandev.dev; dev;
-				     dev = *((struct net_device**)dev->priv)) {
-					chan=dev->priv;
-					if (chan->common.usedby == API){
-						send_oob_msg(card,dev,mbox);				
-					}
-				}
-
-				/* The modem OOB message will probably kill the
-				 * the link. If we don't clear the flag here,
-				 * a deadlock could occur */ 
-				if (atomic_read(&card->u.x.command_busy)){
-					atomic_set(&card->u.x.command_busy,0);
-				}
-			}
-		}
-	}
-
-	memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-	mbox->cmd.command = X25_HDLC_LINK_STATUS;
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	if (err){ 
-		x25_error(card, err, X25_HDLC_LINK_STATUS, 0);
-	}
-
-}
-
-/*====================================================================
- * 	Network event interrupt handler.
- *===================================================================*/
-static void event_intr (sdla_t* card)
-{
-	x25_fetch_events(card);
-}
-
-/*====================================================================
- * 	Spurious interrupt handler.
- * 	o print a warning
- * 	o	 
- *====================================================================*/
-
-static void spur_intr (sdla_t* card)
-{
-	printk(KERN_INFO "%s: spurious interrupt!\n", card->devname);
-}
-
-
-/*
- *	Background Polling Routines  
- */
-
-/*====================================================================
- * 	Main polling routine.
- * 	This routine is repeatedly called by the WANPIPE 'thread' to allow for
- * 	time-dependent housekeeping work.
- *
- * 	Notes:
- * 	1. This routine may be called on interrupt context with all interrupts
- *    	enabled. Beware!
- *====================================================================*/
-
-static void wpx_poll (sdla_t *card)
-{
-	if (!card->wandev.dev){
-		goto wpx_poll_exit;
-	}
-
-	if (card->open_cnt != card->u.x.num_of_ch){
-		goto wpx_poll_exit;
-	}
-	
-	if (test_bit(PERI_CRIT,&card->wandev.critical)){
-		goto wpx_poll_exit;
-	}
-
-	if (test_bit(SEND_CRIT,&card->wandev.critical)){
-		goto wpx_poll_exit;
-	}
-
-	switch(card->wandev.state){
-		case WAN_CONNECTED:
-			poll_active(card);
-			break;
-
-		case WAN_CONNECTING:
-			poll_connecting(card);
-			break;
-
-		case WAN_DISCONNECTED:
-			poll_disconnected(card);
-			break;
-	}
-
-wpx_poll_exit:
-	clear_bit(POLL_CRIT,&card->wandev.critical);
-	return;
-}
-
-static void trigger_x25_poll(sdla_t *card)
-{
-	schedule_work(&card->u.x.x25_poll_work);
-}
-
-/*====================================================================
- * 	Handle physical link establishment phase.
- * 	o if connection timed out, disconnect the link.
- *===================================================================*/
-
-static void poll_connecting (sdla_t* card)
-{
-	volatile TX25Status* status = card->flags;
-
-	if (status->gflags & X25_HDLC_ABM){
-
-		timer_intr_exec (card, TMR_INT_ENABLED_POLL_CONNECT_ON);
-
-	}else if ((jiffies - card->state_tick) > CONNECT_TIMEOUT){
-
-		timer_intr_exec (card, TMR_INT_ENABLED_POLL_CONNECT_OFF);
-
-	}
-}
-
-/*====================================================================
- * 	Handle physical link disconnected phase.
- * 	o if hold-down timeout has expired and there are open interfaces, 
- *	connect link.
- *===================================================================*/
-
-static void poll_disconnected (sdla_t* card)
-{
-	struct net_device *dev; 
-	x25_channel_t *chan;
-	TX25Status* status = card->flags;
-
-	if (!card->u.x.LAPB_hdlc && card->open_cnt && 
-	    ((jiffies - card->state_tick) > HOLD_DOWN_TIME)){
-		timer_intr_exec(card, TMR_INT_ENABLED_POLL_DISCONNECT);
-	}
-
-
-	if ((dev=card->wandev.dev) == NULL)
-		return;
-
-	if ((chan=dev->priv) == NULL)
-		return;
-
-	if (chan->common.usedby == API && 
-	    atomic_read(&chan->common.command) && 
-	    card->u.x.LAPB_hdlc){
-
-		if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_CMD_EXEC)) 
-			card->u.x.timer_int_enabled |= TMR_INT_ENABLED_CMD_EXEC;
-
-		if (!(status->imask & INTR_ON_TIMER))
-			status->imask |= INTR_ON_TIMER;
-	}	
-
-}
-
-/*====================================================================
- * 	Handle active link phase.
- * 	o fetch X.25 asynchronous events.
- * 	o kick off transmission on all interfaces.
- *===================================================================*/
-
-static void poll_active (sdla_t* card)
-{
-	struct net_device* dev;
-	TX25Status* status = card->flags;
-
-	for (dev = card->wandev.dev; dev;
-	     dev = *((struct net_device **)dev->priv)){
-		x25_channel_t* chan = dev->priv;
-
-		/* If SVC has been idle long enough, close virtual circuit */
-		if ( chan->common.svc && 
-		     chan->common.state == WAN_CONNECTED &&
-		     chan->common.usedby == WANPIPE ){
-		
-			if( (jiffies - chan->i_timeout_sofar) / HZ > chan->idle_timeout ){
-				/* Close svc */
-				card->u.x.poll_device=dev;
-				timer_intr_exec	(card, TMR_INT_ENABLED_POLL_ACTIVE);
-			}
-		}
-
-#ifdef PRINT_DEBUG
-		chan->ifstats.tx_compressed = atomic_read(&chan->common.command);
-		chan->ifstats.tx_errors = chan->common.state;
-		chan->ifstats.rx_fifo_errors = atomic_read(&card->u.x.command_busy);
-		++chan->ifstats.tx_bytes;
-
-		chan->ifstats.rx_fifo_errors=atomic_read(&chan->common.disconnect);
-		chan->ifstats.multicast=atomic_read(&chan->bh_buff_used);
-		chan->ifstats.rx_length_errors=*card->u.x.hdlc_buf_status;
-#endif	
-
-		if (chan->common.usedby == API && 
-		    atomic_read(&chan->common.command) && 
-	            !card->u.x.LAPB_hdlc){
-
-			if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_CMD_EXEC)) 
-				card->u.x.timer_int_enabled |= TMR_INT_ENABLED_CMD_EXEC;
-
-			if (!(status->imask & INTR_ON_TIMER))
-				status->imask |= INTR_ON_TIMER;
-		}	
-
-		if ((chan->common.usedby == API) && 
-		     atomic_read(&chan->common.disconnect)){
-
-			if (chan->common.state == WAN_DISCONNECTED){
-				atomic_set(&chan->common.disconnect,0);
-				return;
-			}
-
-			atomic_set(&chan->common.command,X25_CLEAR_CALL);
-			if (!(card->u.x.timer_int_enabled & TMR_INT_ENABLED_CMD_EXEC)) 
-				card->u.x.timer_int_enabled |= TMR_INT_ENABLED_CMD_EXEC;
-
-			if (!(status->imask & INTR_ON_TIMER))
-				status->imask |= INTR_ON_TIMER;
-		}
-	}
-}
-
-static void timer_intr_exec(sdla_t *card, unsigned char TYPE)
-{
-	TX25Status* status = card->flags;
-	card->u.x.timer_int_enabled |= TYPE;
-	if (!(status->imask & INTR_ON_TIMER))
-		status->imask |= INTR_ON_TIMER;
-}
-
-
-/*==================================================================== 
- * SDLA Firmware-Specific Functions 
- *
- *  Almost all X.25 commands can unexpetedly fail due to so called 'X.25
- *  asynchronous events' such as restart, interrupt, incoming call request,
- *  call clear request, etc.  They can't be ignored and have to be delt with
- *  immediately.  To tackle with this problem we execute each interface 
- *  command in a loop until good return code is received or maximum number 
- *  of retries is reached.  Each interface command returns non-zero return 
- *  code, an asynchronous event/error handler x25_error() is called.
- *====================================================================*/
-
-/*====================================================================
- * 	Read X.25 firmware version.
- *		Put code version as ASCII string in str. 
- *===================================================================*/
-
-static int x25_get_version (sdla_t* card, char* str)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.command = X25_READ_CODE_VERSION;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- &&
-		 x25_error(card, err, X25_READ_CODE_VERSION, 0));
-
-	if (!err && str)
-	{
-		int len = mbox->cmd.length;
-
-		memcpy(str, mbox->data, len);
-		str[len] = '\0';
-	}
-	return err;
-}
-
-/*====================================================================
- * 	Configure adapter.
- *===================================================================*/
-
-static int x25_configure (sdla_t* card, TX25Config* conf)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		memcpy(mbox->data, (void*)conf, sizeof(TX25Config));
-		mbox->cmd.length  = sizeof(TX25Config);
-		mbox->cmd.command = X25_SET_CONFIGURATION;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_SET_CONFIGURATION, 0));
-	return err;
-}
-
-/*====================================================================
- * 	Configure adapter for HDLC only.
- *===================================================================*/
-
-static int hdlc_configure (sdla_t* card, TX25Config* conf)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		memcpy(mbox->data, (void*)conf, sizeof(TX25Config));
-		mbox->cmd.length  = sizeof(TX25Config);
-		mbox->cmd.command = X25_HDLC_SET_CONFIG;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_SET_CONFIGURATION, 0));
-
-	return err;
-}
-
-static int set_hdlc_level (sdla_t* card)
-{
-
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.command = SET_PROTOCOL_LEVEL;
-		mbox->cmd.length = 1;
-		mbox->data[0] = HDLC_LEVEL; //| DO_HDLC_LEVEL_ERROR_CHECKING; 	
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, SET_PROTOCOL_LEVEL, 0));
-
-	return err;
-}
-
-
-
-/*====================================================================
- * Get communications error statistics.
- *====================================================================*/
-
-static int x25_get_err_stats (sdla_t* card)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.command = X25_HDLC_READ_COMM_ERR;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_HDLC_READ_COMM_ERR, 0));
-	
-	if (!err)
-	{
-		THdlcCommErr* stats = (void*)mbox->data;
-
-		card->wandev.stats.rx_over_errors    = stats->rxOverrun;
-		card->wandev.stats.rx_crc_errors     = stats->rxBadCrc;
-		card->wandev.stats.rx_missed_errors  = stats->rxAborted;
-		card->wandev.stats.tx_aborted_errors = stats->txAborted;
-	}
-	return err;
-}
-
-/*====================================================================
- * 	Get protocol statistics.
- *===================================================================*/
-
-static int x25_get_stats (sdla_t* card)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.command = X25_READ_STATISTICS;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_READ_STATISTICS, 0)) ;
-	
-	if (!err)
-	{
-		TX25Stats* stats = (void*)mbox->data;
-
-		card->wandev.stats.rx_packets = stats->rxData;
-		card->wandev.stats.tx_packets = stats->txData;
-	}
-	return err;
-}
-
-/*====================================================================
- * 	Close HDLC link.
- *===================================================================*/
-
-static int x25_close_hdlc (sdla_t* card)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.command = X25_HDLC_LINK_CLOSE;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_HDLC_LINK_CLOSE, 0));
-	
-	return err;
-}
-
-
-/*====================================================================
- * 	Open HDLC link.
- *===================================================================*/
-
-static int x25_open_hdlc (sdla_t* card)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.command = X25_HDLC_LINK_OPEN;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_HDLC_LINK_OPEN, 0));
-
-	return err;
-}
-
-/*=====================================================================
- * Setup HDLC link.
- *====================================================================*/
-static int x25_setup_hdlc (sdla_t* card)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.command = X25_HDLC_LINK_SETUP;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_HDLC_LINK_SETUP, 0));
-	
-	return err;
-}
-
-/*====================================================================
- * Set (raise/drop) DTR.
- *===================================================================*/
-
-static int x25_set_dtr (sdla_t* card, int dtr)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->data[0] = 0;
-		mbox->data[2] = 0;
-		mbox->data[1] = dtr ? 0x02 : 0x01;
-		mbox->cmd.length  = 3;
-		mbox->cmd.command = X25_SET_GLOBAL_VARS;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_SET_GLOBAL_VARS, 0));
-	
-	return err;
-}
-
-/*====================================================================
- * 	Set interrupt mode.
- *===================================================================*/
-
-static int x25_set_intr_mode (sdla_t* card, int mode)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->data[0] = mode;
-		if (card->hw.fwid == SFID_X25_508){
-			mbox->data[1] = card->hw.irq;
-			mbox->data[2] = 2;
-			mbox->cmd.length = 3;
-		}else {
-		 	mbox->cmd.length  = 1;
-		}
-		mbox->cmd.command = X25_SET_INTERRUPT_MODE;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_SET_INTERRUPT_MODE, 0));
-	
-	return err;
-}
-
-/*====================================================================
- * 	Read X.25 channel configuration.
- *===================================================================*/
-
-static int x25_get_chan_conf (sdla_t* card, x25_channel_t* chan)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int lcn = chan->common.lcn;
-	int err;
-
-	do{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.lcn     = lcn;
-		mbox->cmd.command = X25_READ_CHANNEL_CONFIG;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_READ_CHANNEL_CONFIG, lcn));
-
-	if (!err)
-	{
-		TX25Status* status = card->flags;
-
-		/* calculate an offset into the array of status bytes */
-		if (card->u.x.hi_svc <= X25_MAX_CHAN){ 
-
-			chan->ch_idx = lcn - 1;
-
-		}else{
-			int offset;
-
-			/* FIX: Apr 14 2000 : Nenad Corbic
-			 * The data field was being compared to 0x1F using
-                         * '&&' instead of '&'. 
-			 * This caused X25API to fail for LCNs greater than 255.
-			 */
-			switch (mbox->data[0] & 0x1F)
-			{
-				case 0x01: 
-					offset = status->pvc_map; break;
-				case 0x03: 
-					offset = status->icc_map; break;
-				case 0x07: 
-					offset = status->twc_map; break;
-				case 0x0B: 
-					offset = status->ogc_map; break;
-				default: 
-					offset = 0;
-			}
-			chan->ch_idx = lcn - 1 - offset;
-		}
-
-		/* get actual transmit packet size on this channel */
-		switch(mbox->data[1] & 0x38)
-		{
-			case 0x00: 
-				chan->tx_pkt_size = 16; 
-				break;
-			case 0x08: 
-				chan->tx_pkt_size = 32; 
-				break;
-			case 0x10: 
-				chan->tx_pkt_size = 64; 
-				break;
-			case 0x18: 
-				chan->tx_pkt_size = 128; 
-				break;
-			case 0x20: 
-				chan->tx_pkt_size = 256; 
-				break;
-			case 0x28: 
-				chan->tx_pkt_size = 512; 
-				break;
-			case 0x30: 
-				chan->tx_pkt_size = 1024; 
-				break;
-		}
-		if (card->u.x.logging)
-			printk(KERN_INFO "%s: X.25 packet size on LCN %d is %d.\n",
-				card->devname, lcn, chan->tx_pkt_size);
-	}
-	return err;
-}
-
-/*====================================================================
- * 	Place X.25 call.
- *====================================================================*/
-
-static int x25_place_call (sdla_t* card, x25_channel_t* chan)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-	char str[64];
-
-
-	if (chan->protocol == htons(ETH_P_IP)){
-		sprintf(str, "-d%s -uCC", chan->addr);
-	
-	}else if (chan->protocol == htons(ETH_P_IPX)){
-		sprintf(str, "-d%s -u800000008137", chan->addr);
-	
-	}
-	
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		strcpy(mbox->data, str);
-		mbox->cmd.length  = strlen(str);
-		mbox->cmd.command = X25_PLACE_CALL;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_PLACE_CALL, 0));
-
-	if (!err){
-		bind_lcn_to_dev (card, chan->dev, mbox->cmd.lcn);
-	}
-	return err;
-}
-
-/*====================================================================
- * 	Accept X.25 call.
- *====================================================================*/
-
-static int x25_accept_call (sdla_t* card, int lcn, int qdm)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.lcn     = lcn;
-		mbox->cmd.qdm     = qdm;
-		mbox->cmd.command = X25_ACCEPT_CALL;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_ACCEPT_CALL, lcn));
-	
-	return err;
-}
-
-/*====================================================================
- * 	Clear X.25 call.
- *====================================================================*/
-
-static int x25_clear_call (sdla_t* card, int lcn, int cause, int diagn)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.lcn     = lcn;
-		mbox->cmd.cause   = cause;
-		mbox->cmd.diagn   = diagn;
-		mbox->cmd.command = X25_CLEAR_CALL;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, X25_CLEAR_CALL, lcn));
-	
-	return err;
-}
-
-/*====================================================================
- * 	Send X.25 data packet.
- *====================================================================*/
-
-static int x25_send (sdla_t* card, int lcn, int qdm, int len, void* buf)
-{
-	TX25Mbox* mbox = card->mbox;
-  	int retry = MAX_CMD_RETRY;
-	int err;
-	unsigned char cmd;
-		
-	if (card->u.x.LAPB_hdlc)
-		cmd = X25_HDLC_WRITE;
-	else
-		cmd = X25_WRITE;
-
-	do
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		memcpy(mbox->data, buf, len);
-		mbox->cmd.length  = len;
-		mbox->cmd.lcn     = lcn;
-
-		if (card->u.x.LAPB_hdlc){
-			mbox->cmd.pf = qdm;
-		}else{			
-			mbox->cmd.qdm = qdm;
-		}
-
-		mbox->cmd.command = cmd;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	} while (err && retry-- && x25_error(card, err, cmd , lcn));
-
-
-	/* If buffers are busy the return code for LAPB HDLC is
-         * 1. The above functions are looking for return code
-         * of X25RES_NOT_READY if busy. */
-
-	if (card->u.x.LAPB_hdlc && err == 1){
-		err = X25RES_NOT_READY;
-	}
-
-	return err;
-}
-
-/*====================================================================
- * 	Fetch X.25 asynchronous events.
- *===================================================================*/
-
-static int x25_fetch_events (sdla_t* card)
-{
-	TX25Status* status = card->flags;
-	TX25Mbox* mbox = card->mbox;
-	int err = 0;
-
-	if (status->gflags & 0x20)
-	{
-		memset(&mbox->cmd, 0, sizeof(TX25Cmd));
-		mbox->cmd.command = X25_IS_DATA_AVAILABLE;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
- 		if (err) x25_error(card, err, X25_IS_DATA_AVAILABLE, 0);
-	}
-	return err;
-}
-
-/*====================================================================
- * 	X.25 asynchronous event/error handler.
- *		This routine is called each time interface command returns 
- *		non-zero return code to handle X.25 asynchronous events and 
- *		common errors. Return non-zero to repeat command or zero to 
- *		cancel it.
- *
- * 	Notes:
- * 	1. This function may be called recursively, as handling some of the
- *    	asynchronous events (e.g. call request) requires execution of the
- *    	interface command(s) that, in turn, may also return asynchronous
- *    	events.  To avoid re-entrancy problems we copy mailbox to dynamically
- *    	allocated memory before processing events.
- *====================================================================*/
-
-static int x25_error (sdla_t* card, int err, int cmd, int lcn)
-{
-	int retry = 1;
-	unsigned dlen = ((TX25Mbox*)card->mbox)->cmd.length;
-	TX25Mbox* mb;
-
-	mb = kmalloc(sizeof(TX25Mbox) + dlen, GFP_ATOMIC);
-	if (mb == NULL)
-	{
-		printk(KERN_ERR "%s: x25_error() out of memory!\n",
-			card->devname);
-		return 0;
-	}
-	memcpy(mb, card->mbox, sizeof(TX25Mbox) + dlen);
-	switch (err){
-
-	case X25RES_ASYNC_PACKET:	/* X.25 asynchronous packet was received */
-
-		mb->data[dlen] = '\0';
-
-		switch (mb->cmd.pktType & 0x7F){
-
-		case ASE_CALL_RQST:		/* incoming call */
-			retry = incoming_call(card, cmd, lcn, mb);
-			break;
-
-		case ASE_CALL_ACCEPTED:		/* connected */
-			retry = call_accepted(card, cmd, lcn, mb);
-			break;
-
-		case ASE_CLEAR_RQST:		/* call clear request */
-			retry = call_cleared(card, cmd, lcn, mb);
-			break;
-
-		case ASE_RESET_RQST:		/* reset request */
-			printk(KERN_INFO "%s: X.25 reset request on LCN %d! "
-				"Cause:0x%02X Diagn:0x%02X\n",
-				card->devname, mb->cmd.lcn, mb->cmd.cause,
-				mb->cmd.diagn);
-			api_oob_event (card,mb);
-			break;
-
-		case ASE_RESTART_RQST:		/* restart request */
-			retry = restart_event(card, cmd, lcn, mb);
-			break;
-
-		case ASE_CLEAR_CONFRM:
-			if (clear_confirm_event (card,mb))
-				break;
-
-			/* I use the goto statement here so if 
-	                 * somebody inserts code between the
-        	         * case and default, we will not have
-                	 * ghost problems */
-
-			goto dflt_1;
-
-		default:
-dflt_1:
-			printk(KERN_INFO "%s: X.25 event 0x%02X on LCN %d! "
-				"Cause:0x%02X Diagn:0x%02X\n",
-				card->devname, mb->cmd.pktType,
-				mb->cmd.lcn, mb->cmd.cause, mb->cmd.diagn);
-		}
-		break;
-
-	case X25RES_PROTO_VIOLATION:	/* X.25 protocol violation indication */
-
-		/* Bug Fix: Mar 14 2000
-                 * The Protocol violation error conditions were  
-                 * not handled previously */
-
-		switch (mb->cmd.pktType & 0x7F){
-
-		case PVE_CLEAR_RQST:	/* Clear request */		
-			retry = call_cleared(card, cmd, lcn, mb);
-			break;	
-
-		case PVE_RESET_RQST:	/* Reset request */
-			printk(KERN_INFO "%s: X.25 reset request on LCN %d! "
-				"Cause:0x%02X Diagn:0x%02X\n",
-				card->devname, mb->cmd.lcn, mb->cmd.cause,
-				mb->cmd.diagn);
-			api_oob_event (card,mb);
-			break;
-
-		case PVE_RESTART_RQST:	/* Restart request */
-			retry = restart_event(card, cmd, lcn, mb);
-			break;
-
-		default :
-			printk(KERN_INFO
-				"%s: X.25 protocol violation on LCN %d! "
-				"Packet:0x%02X Cause:0x%02X Diagn:0x%02X\n",
-				card->devname, mb->cmd.lcn,
-				mb->cmd.pktType & 0x7F, mb->cmd.cause, mb->cmd.diagn);
-			api_oob_event(card,mb);
-		}
-		break;
-
-	case 0x42:	/* X.25 timeout */
-		retry = timeout_event(card, cmd, lcn, mb);
-		break;
-
-	case 0x43:	/* X.25 retry limit exceeded */
-		printk(KERN_INFO
-			"%s: exceeded X.25 retry limit on LCN %d! "
-			"Packet:0x%02X Diagn:0x%02X\n", card->devname,
-			mb->cmd.lcn, mb->cmd.pktType, mb->cmd.diagn)
-		;
-		break;
-
-	case 0x08:	/* modem failure */
-#ifndef MODEM_NOT_LOG
-		printk(KERN_INFO "%s: modem failure!\n", card->devname);
-#endif /* MODEM_NOT_LOG */
-		api_oob_event(card,mb);
-		break;
-
-	case 0x09:	/* N2 retry limit */
-		printk(KERN_INFO "%s: exceeded HDLC retry limit!\n",
-			card->devname);
-		api_oob_event(card,mb);
-		break;
-
-	case 0x06:	/* unnumbered frame was received while in ABM */
-		printk(KERN_INFO "%s: received Unnumbered frame 0x%02X!\n",
-			card->devname, mb->data[0]);
-		api_oob_event(card,mb);
-		break;
-
-	case CMD_TIMEOUT:
-		printk(KERN_ERR "%s: command 0x%02X timed out!\n",
-			card->devname, cmd)
-		;
-		retry = 0;	/* abort command */
-		break;
-
-	case X25RES_NOT_READY:
-		retry = 1;
-		break;
-
-	case 0x01:
-		if (card->u.x.LAPB_hdlc)
-			break;
-
-		if (mb->cmd.command == 0x16)
-			break;
-		/* I use the goto statement here so if 
-                 * somebody inserts code between the
-                 * case and default, we will not have
-                 * ghost problems */
-		goto dflt_2;
-
-	default:
-dflt_2:
-		printk(KERN_INFO "%s: command 0x%02X returned 0x%02X! Lcn %i\n",
-			card->devname, cmd, err, mb->cmd.lcn)
-		;
-		retry = 0;	/* abort command */
-	}
-	kfree(mb);
-	return retry;
-}
-
-/*==================================================================== 
- *	X.25 Asynchronous Event Handlers
- * 	These functions are called by the x25_error() and should return 0, if
- * 	the command resulting in the asynchronous event must be aborted.
- *====================================================================*/
-
-
-
-/*====================================================================
- *Handle X.25 incoming call request.
- *	RFC 1356 establishes the following rules:
- *	1. The first octet in the Call User Data (CUD) field of the call
- *     	   request packet contains NLPID identifying protocol encapsulation
- * 	2. Calls MUST NOT be accepted unless router supports requested
- *   	   protocol encapsulation.
- *	3. A diagnostic code 249 defined by ISO/IEC 8208 may be used 
- *	   when clearing a call because protocol encapsulation is not 
- *	   supported.
- *	4. If an incoming call is received while a call request is 
- *	   pending (i.e. call collision has occurred), the incoming call 
- *	   shall be rejected and call request shall be retried.
- *====================================================================*/
-
-static int incoming_call (sdla_t* card, int cmd, int lcn, TX25Mbox* mb)
-{
-	struct wan_device* wandev = &card->wandev;
-	int new_lcn = mb->cmd.lcn;
-	struct net_device* dev = get_dev_by_lcn(wandev, new_lcn);
-	x25_channel_t* chan = NULL;
-	int accept = 0;		/* set to '1' if o.k. to accept call */
-	unsigned int user_data;
-	x25_call_info_t* info;
-	
-	/* Make sure there is no call collision */
-	if (dev != NULL)
-	{
-		printk(KERN_INFO
-			"%s: X.25 incoming call collision on LCN %d!\n",
-			card->devname, new_lcn);
-
-		x25_clear_call(card, new_lcn, 0, 0);
-		return 1;
-	}
-
-	/* Make sure D bit is not set in call request */
-//FIXME: THIS IS NOT TURE !!!! TAKE IT OUT
-//	if (mb->cmd.qdm & 0x02)
-//	{
-//		printk(KERN_INFO
-//			"%s: X.25 incoming call on LCN %d with D-bit set!\n",
-//			card->devname, new_lcn);
-//
-//		x25_clear_call(card, new_lcn, 0, 0);
-//		return 1;
-//	}
-
-	/* Parse call request data */
-	info = kmalloc(sizeof(x25_call_info_t), GFP_ATOMIC);
-	if (info == NULL)
-	{
-		printk(KERN_ERR
-			"%s: not enough memory to parse X.25 incoming call "
-			"on LCN %d!\n", card->devname, new_lcn);
-		x25_clear_call(card, new_lcn, 0, 0);
-		return 1;
-	}
- 
-	parse_call_info(mb->data, info);
-
-	if (card->u.x.logging)
-		printk(KERN_INFO "\n%s: X.25 incoming call on LCN %d!\n",
-			card->devname, new_lcn);
-
-	/* Conver the first two ASCII characters into an
-         * interger. Used to check the incoming protocol 
-         */
-	user_data = hex_to_uint(info->user,2);
-
-	/* Find available channel */
-	for (dev = wandev->dev; dev; dev = *((struct net_device **)dev->priv)) {
-		chan = dev->priv;
-
-		if (chan->common.usedby == API)
-			continue;
-
-		if (!chan->common.svc || (chan->common.state != WAN_DISCONNECTED))
-			continue;
-
-		if (user_data == NLPID_IP && chan->protocol != htons(ETH_P_IP)){
-			printk(KERN_INFO "IP packet but configured for IPX : %x, %x\n",
-				       htons(chan->protocol), info->user[0]);
-			continue;
-		}
-	
-		if (user_data == NLPID_SNAP && chan->protocol != htons(ETH_P_IPX)){
-			printk(KERN_INFO "IPX packet but configured for IP: %x\n",
-				       htons(chan->protocol));
-			continue;
-		}
-		if (strcmp(info->src, chan->addr) == 0)
-			break;
-
-	        /* If just an '@' is specified, accept all incoming calls */
-	        if (strcmp(chan->addr, "") == 0)
-	                break;
-	}
-
-	if (dev == NULL){
-
-		/* If the call is not for any WANPIPE interfaces
-                 * check to see if there is an API listening queue
-                 * waiting for data. If there is send the packet
-                 * up the stack.
-                 */
-		if (card->sk != NULL && card->func != NULL){
-			if (api_incoming_call(card,mb,new_lcn)){
-				x25_clear_call(card, new_lcn, 0, 0);
-			}
-			accept = 0;
-		}else{
-			printk(KERN_INFO "%s: no channels available!\n",
-				card->devname);
-			
-			x25_clear_call(card, new_lcn, 0, 0);
-		}
-
-	}else if (info->nuser == 0){
-
-		printk(KERN_INFO
-			"%s: no user data in incoming call on LCN %d!\n",
-			card->devname, new_lcn)
-		;
-		x25_clear_call(card, new_lcn, 0, 0);
-
-	}else switch (info->user[0]){
-
-		case 0:		/* multiplexed */
-			chan->protocol = htons(0);
-			accept = 1;
-			break;
-
-		case NLPID_IP:	/* IP datagrams */
-			accept = 1;
-			break;
-
-		case NLPID_SNAP: /* IPX datagrams */
-			accept = 1;
-			break;
-
-		default:
-			printk(KERN_INFO
-				"%s: unsupported NLPID 0x%02X in incoming call "
-				"on LCN %d!\n", card->devname, info->user[0], new_lcn);
-			x25_clear_call(card, new_lcn, 0, 249);
-	}
-	
-	if (accept && (x25_accept_call(card, new_lcn, 0) == CMD_OK)){
-
-		bind_lcn_to_dev (card, chan->dev, new_lcn);
-		
-		if (x25_get_chan_conf(card, chan) == CMD_OK)
-			set_chan_state(dev, WAN_CONNECTED);
-		else 
-			x25_clear_call(card, new_lcn, 0, 0);
-	}
-	kfree(info);
-	return 1;
-}
-
-/*====================================================================
- * 	Handle accepted call.
- *====================================================================*/
-
-static int call_accepted (sdla_t* card, int cmd, int lcn, TX25Mbox* mb)
-{
-	unsigned new_lcn = mb->cmd.lcn;
-	struct net_device* dev = find_channel(card, new_lcn);
-	x25_channel_t* chan;
-
-	if (dev == NULL){
-		printk(KERN_INFO
-			"%s: clearing orphaned connection on LCN %d!\n",
-			card->devname, new_lcn);
-		x25_clear_call(card, new_lcn, 0, 0);
-		return 1;
-	}
-
-	if (card->u.x.logging)	
-		printk(KERN_INFO "%s: X.25 call accepted on Dev %s and LCN %d!\n",
-			card->devname, dev->name, new_lcn);
-
-	/* Get channel configuration and notify router */
-	chan = dev->priv;
-	if (x25_get_chan_conf(card, chan) != CMD_OK)
-	{
-		x25_clear_call(card, new_lcn, 0, 0);
-		return 1;
-	}
-
-	set_chan_state(dev, WAN_CONNECTED);
-
-	if (chan->common.usedby == API){
-		send_delayed_cmd_result(card,dev,mb);
-		bind_lcn_to_dev (card, dev, new_lcn);
-	}
-
-	return 1;
-}
-
-/*====================================================================
- * 	Handle cleared call.
- *====================================================================*/
-
-static int call_cleared (sdla_t* card, int cmd, int lcn, TX25Mbox* mb)
-{
-	unsigned new_lcn = mb->cmd.lcn;
-	struct net_device* dev = find_channel(card, new_lcn);
-	x25_channel_t *chan;
-	unsigned char old_state;
-
-	if (card->u.x.logging){
-		printk(KERN_INFO "%s: X.25 clear request on LCN %d! Cause:0x%02X "
-		"Diagn:0x%02X\n",
-		card->devname, new_lcn, mb->cmd.cause, mb->cmd.diagn);
-	}
-
-	if (dev == NULL){ 
-		printk(KERN_INFO "%s: X.25 clear request : No device for clear\n",
-				card->devname);
-		return 1;
-	}
-
-	chan=dev->priv;
-
-	old_state = chan->common.state;
-
-	set_chan_state(dev, WAN_DISCONNECTED);
-
-	if (chan->common.usedby == API){
-
-		switch (old_state){
-		
-		case WAN_CONNECTING:
-			send_delayed_cmd_result(card,dev,mb);
-			break;
-		case WAN_CONNECTED:
-			send_oob_msg(card,dev,mb);				
-			break;
-		}
-	}
-	
-	return ((cmd == X25_WRITE) && (lcn == new_lcn)) ? 0 : 1;
-}
-
-/*====================================================================
- * 	Handle X.25 restart event.
- *====================================================================*/
-
-static int restart_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb)
-{
-	struct wan_device* wandev = &card->wandev;
-	struct net_device* dev;
-	x25_channel_t *chan;
-	unsigned char old_state;
-
-	printk(KERN_INFO
-		"%s: X.25 restart request! Cause:0x%02X Diagn:0x%02X\n",
-		card->devname, mb->cmd.cause, mb->cmd.diagn);
-
-	/* down all logical channels */
-	for (dev = wandev->dev; dev; dev = *((struct net_device **)dev->priv)) {
-		chan=dev->priv;
-		old_state = chan->common.state;
-
-		set_chan_state(dev, WAN_DISCONNECTED);
-
-		if (chan->common.usedby == API){
-			switch (old_state){
-		
-			case WAN_CONNECTING:
-				send_delayed_cmd_result(card,dev,mb);
-				break;
-			case WAN_CONNECTED:
-				send_oob_msg(card,dev,mb);				
-				break;
-			}
-		}
-	}
-	return (cmd == X25_WRITE) ? 0 : 1;
-}
-
-/*====================================================================
- * Handle timeout event.
- *====================================================================*/
-
-static int timeout_event (sdla_t* card, int cmd, int lcn, TX25Mbox* mb)
-{
-	unsigned new_lcn = mb->cmd.lcn;
-
-	if (mb->cmd.pktType == 0x05)	/* call request time out */
-	{
-		struct net_device* dev = find_channel(card,new_lcn);
-
-		printk(KERN_INFO "%s: X.25 call timed timeout on LCN %d!\n",
-			card->devname, new_lcn);
-
-		if (dev){
-			x25_channel_t *chan = dev->priv;
-			set_chan_state(dev, WAN_DISCONNECTED);
-
-			if (chan->common.usedby == API){
-				send_delayed_cmd_result(card,dev,card->mbox);
-			}
-		}
-	}else{ 
-		printk(KERN_INFO "%s: X.25 packet 0x%02X timeout on LCN %d!\n",
-		card->devname, mb->cmd.pktType, new_lcn);
-	}
-	return 1;
-}
-
-/* 
- *	Miscellaneous 
- */
-
-/*====================================================================
- * 	Establish physical connection.
- * 	o open HDLC and raise DTR
- *
- * 	Return:		0	connection established
- *			1	connection is in progress
- *			<0	error
- *===================================================================*/
-
-static int connect (sdla_t* card)
-{
-	TX25Status* status = card->flags;
-
-	if (x25_open_hdlc(card) || x25_setup_hdlc(card))
-		return -EIO;
-
-	wanpipe_set_state(card, WAN_CONNECTING);
-
-	x25_set_intr_mode(card, INTR_ON_TIMER); 
-	status->imask &= ~INTR_ON_TIMER;
-
-	return 1;
-}
-
-/*
- * 	Tear down physical connection.
- * 	o close HDLC link
- * 	o drop DTR
- *
- * 	Return:		0
- *			<0	error
- */
-
-static int disconnect (sdla_t* card)
-{
-	wanpipe_set_state(card, WAN_DISCONNECTED);
-	x25_set_intr_mode(card, INTR_ON_TIMER);	/* disable all interrupt except timer */
-	x25_close_hdlc(card);			/* close HDLC link */
-	x25_set_dtr(card, 0);			/* drop DTR */
-	return 0;
-}
-
-/*
- * Find network device by its channel number.
- */
-
-static struct net_device* get_dev_by_lcn(struct wan_device* wandev,
-					 unsigned lcn)
-{
-	struct net_device* dev;
-
-	for (dev = wandev->dev; dev; dev = *((struct net_device **)dev->priv))
-		if (((x25_channel_t*)dev->priv)->common.lcn == lcn) 
-			break;
-	return dev;
-}
-
-/*
- * 	Initiate connection on the logical channel.
- * 	o for PVC we just get channel configuration
- * 	o for SVCs place an X.25 call
- *
- * 	Return:		0	connected
- *			>0	connection in progress
- *			<0	failure
- */
-
-static int chan_connect(struct net_device* dev)
-{
-	x25_channel_t* chan = dev->priv;
-	sdla_t* card = chan->card;
-
-	if (chan->common.svc && chan->common.usedby == WANPIPE){
-		if (!chan->addr[0]){
-			printk(KERN_INFO "%s: No Destination Address\n",
-					card->devname);
-			return -EINVAL;	/* no destination address */
-		}
-		printk(KERN_INFO "%s: placing X.25 call to %s ...\n",
-			card->devname, chan->addr);
-
-		if (x25_place_call(card, chan) != CMD_OK)
-			return -EIO;
-
-		set_chan_state(dev, WAN_CONNECTING);
-		return 1;
-	}else{
-		if (x25_get_chan_conf(card, chan) != CMD_OK)
-			return -EIO;
-
-		set_chan_state(dev, WAN_CONNECTED);
-	}
-	return 0;
-}
-
-/*
- * 	Disconnect logical channel.
- * 	o if SVC then clear X.25 call
- */
-
-static int chan_disc(struct net_device* dev)
-{
-	x25_channel_t* chan = dev->priv;
-
-	if (chan->common.svc){ 
-		x25_clear_call(chan->card, chan->common.lcn, 0, 0);
-
-		/* For API we disconnect on clear
-                 * confirmation. 
-                 */
-		if (chan->common.usedby == API)
-			return 0;
-	}
-
-	set_chan_state(dev, WAN_DISCONNECTED);
-	
-	return 0;
-}
-
-/*
- * 	Set logical channel state.
- */
-
-static void set_chan_state(struct net_device* dev, int state)
-{
-	x25_channel_t* chan = dev->priv;
-	sdla_t* card = chan->card;
-	unsigned long flags;
-
-	save_flags(flags);
-	cli();
-	if (chan->common.state != state)
-	{
-		switch (state)
-		{
-			case WAN_CONNECTED:
-				if (card->u.x.logging){
-					printk (KERN_INFO 
-						"%s: interface %s connected, lcn %i !\n", 
-						card->devname, dev->name,chan->common.lcn);
-				}
-				*(unsigned short*)dev->dev_addr = htons(chan->common.lcn);
-				chan->i_timeout_sofar = jiffies;
-
-				/* LAPB is PVC Based */
-				if (card->u.x.LAPB_hdlc)
-					chan->common.svc=0;
-				break;
-
-			case WAN_CONNECTING:
-				if (card->u.x.logging){
-					printk (KERN_INFO 
-						"%s: interface %s connecting, lcn %i ...\n", 
-						card->devname, dev->name, chan->common.lcn);
-				}
-				break;
-
-			case WAN_DISCONNECTED:
-				if (card->u.x.logging){
-					printk (KERN_INFO 
-						"%s: interface %s disconnected, lcn %i !\n", 
-						card->devname, dev->name,chan->common.lcn);
-				}
-				atomic_set(&chan->common.disconnect,0);
-				
-				if (chan->common.svc) {
-					*(unsigned short*)dev->dev_addr = 0;
-					card->u.x.svc_to_dev_map[(chan->common.lcn%X25_MAX_CHAN)]=NULL;
-		                	chan->common.lcn = 0;
-				}
-
-				if (chan->transmit_length){
-					chan->transmit_length=0;
-					atomic_set(&chan->common.driver_busy,0);
-					chan->tx_offset=0;
-					if (netif_queue_stopped(dev)){
-						netif_wake_queue(dev);
-					}
-				}
-				atomic_set(&chan->common.command,0);
-				break;
-
-			case WAN_DISCONNECTING:
-				if (card->u.x.logging){
-					printk (KERN_INFO 
-					"\n%s: interface %s disconnecting, lcn %i ...\n", 
-					card->devname, dev->name,chan->common.lcn);
-				}
-				atomic_set(&chan->common.disconnect,0);
-				break;
-		}
-		chan->common.state = state;
-	}
-	chan->state_tick = jiffies;
-	restore_flags(flags);
-}
-
-/*
- * 	Send packet on a logical channel.
- *		When this function is called, tx_skb field of the channel data 
- *		space points to the transmit socket buffer.  When transmission 
- *		is complete, release socket buffer and reset 'tbusy' flag.
- *
- * 	Return:		0	- transmission complete
- *			1	- busy
- *
- * 	Notes:
- * 	1. If packet length is greater than MTU for this channel, we'll fragment
- *    	the packet into 'complete sequence' using M-bit.
- * 	2. When transmission is complete, an event notification should be issued
- *    	to the router.
- */
-
-static int chan_send(struct net_device* dev, void* buff, unsigned data_len,
-		     unsigned char tx_intr)
-{
-	x25_channel_t* chan = dev->priv;
-	sdla_t* card = chan->card;
-	TX25Status* status = card->flags;
-	unsigned len=0, qdm=0, res=0, orig_len = 0;
-	void *data;
-
-	/* Check to see if channel is ready */
-	if ((!(status->cflags[chan->ch_idx] & 0x40) && !card->u.x.LAPB_hdlc)  || 
-             !(*card->u.x.hdlc_buf_status & 0x40)){ 
-            
-		if (!tx_intr){
-			setup_for_delayed_transmit (dev, buff, data_len);
-			return 0;
-		}else{
-			/* By returning 0 to tx_intr the packet will be dropped */
-			++card->wandev.stats.tx_dropped;
-			++chan->ifstats.tx_dropped;
-			printk(KERN_INFO "%s: ERROR, Tx intr could not send, dropping %s:\n", 
-				card->devname,dev->name);
-			++chan->if_send_stat.if_send_bfr_not_passed_to_adptr;
-			return 0;
-		}
-	}
-
-	if (chan->common.usedby == API){
-		/* Remove the API Header */
-		x25api_hdr_t *api_data = (x25api_hdr_t *)buff;
-
-		/* Set the qdm bits from the packet header 
-                 * User has the option to set the qdm bits
-                 */
-		qdm = api_data->qdm;
-
-		orig_len = len = data_len - sizeof(x25api_hdr_t);
-		data = (unsigned char*)buff + sizeof(x25api_hdr_t);
-	}else{
-		data = buff;
-		orig_len = len = data_len;
-	}	
-
-	if (tx_intr){
-		/* We are in tx_intr, minus the tx_offset from 
-                 * the total length. The tx_offset part of the
-		 * data has already been sent. Also, move the 
-		 * data pointer to proper offset location.
-                 */
-		len -= chan->tx_offset;
-		data = (unsigned char*)data + chan->tx_offset;
-	}
-		
-	/* Check if the packet length is greater than MTU
-         * If YES: Cut the len to MTU and set the M bit 
-         */
-	if (len > chan->tx_pkt_size && !card->u.x.LAPB_hdlc){
-		len = chan->tx_pkt_size;
-		qdm |= M_BIT;		
-	} 
-
-
-	/* Pass only first three bits of the qdm byte to the send
-         * routine. In case user sets any other bit which might
-         * cause errors. 
-         */
-
-	switch(x25_send(card, chan->common.lcn, (qdm&0x07), len, data)){
-		case 0x00:	/* success */
-			chan->i_timeout_sofar = jiffies;
-
-			dev->trans_start=jiffies;
-			
-			if ((qdm & M_BIT) && !card->u.x.LAPB_hdlc){
-				if (!tx_intr){
-					/* The M bit was set, which means that part of the
-                                         * packet has been sent. Copy the packet into a buffer
-				         * and set the offset to len, so on next tx_inter 
-					 * the packet will be sent using the below offset.
-					 */
-					chan->tx_offset += len;
-
-					++chan->ifstats.tx_packets;
-					chan->ifstats.tx_bytes += len;
-					
-					if (chan->tx_offset < orig_len){
-						setup_for_delayed_transmit (dev, buff, data_len);
-					}
-					res=0;
-				}else{
-					/* We are already in tx_inter, thus data is already
-                                         * in the buffer. Update the offset and wait for
-                                         * next tx_intr. We add on to the offset, since data can
-                                         * be X number of times larger than max data size.
-					 */
-					++chan->ifstats.tx_packets;
-					chan->ifstats.tx_bytes += len;
-					
-					++chan->if_send_stat.if_send_bfr_passed_to_adptr;
-					chan->tx_offset += len;
-
-					/* The user can set the qdm bit as well.
-                                         * If the entire packet was sent and qdm is still
-                                         * set, than it's the user who has set the M bit. In that,
-                                         * case indicate that the packet was send by returning 
-					 * 0 and wait for a new packet. Otherwise, wait for next
-                                         * tx interrupt to send the rest of the packet */
-
-					if (chan->tx_offset < orig_len){
-						res=1;
-					}else{	
-						res=0;
-					}
-				}
-			}else{
-				++chan->ifstats.tx_packets;
-				chan->ifstats.tx_bytes += len;
-				++chan->if_send_stat.if_send_bfr_passed_to_adptr;
-				res=0;
-			}
-			break;
-
-		case 0x33:	/* Tx busy */
-			if (tx_intr){
-				printk(KERN_INFO "%s: Tx_intr: Big Error dropping packet %s\n",
-						card->devname,dev->name);
-				++chan->ifstats.tx_dropped;
-				++card->wandev.stats.tx_dropped;
-				++chan->if_send_stat.if_send_bfr_not_passed_to_adptr;
-				res=0;
-			}else{
-				DBG_PRINTK(KERN_INFO 
-					"%s: Send: Big Error should have tx: storring %s\n",
-						card->devname,dev->name);
-				setup_for_delayed_transmit (dev, buff, data_len);	
-				res=1;
-			}
-			break;
-
-		default:	/* failure */
-			++chan->ifstats.tx_errors;
-			if (tx_intr){
-				printk(KERN_INFO "%s: Tx_intr: Failure to send, dropping %s\n",
-					card->devname,dev->name);
-				++chan->ifstats.tx_dropped;
-				++card->wandev.stats.tx_dropped;
-				++chan->if_send_stat.if_send_bfr_not_passed_to_adptr;
-				res=0;
-			}else{
-				DBG_PRINTK(KERN_INFO "%s: Send: Failure to send !!!, storing %s\n",
-					card->devname,dev->name);			
-				setup_for_delayed_transmit (dev, buff, data_len);
-				res=1;
-			}
-			break;	
-	}
-	return res;
-}
-
-
-/*
- * 	Parse X.25 call request data and fill x25_call_info_t structure.
- */
-
-static void parse_call_info (unsigned char* str, x25_call_info_t* info)
-{
-	memset(info, 0, sizeof(x25_call_info_t));
-	for (; *str; ++str)
-	{
-		int i;
-		unsigned char ch;
-
-		if (*str == '-') switch (str[1]) {
-
-			/* Take minus 2 off the maximum size so that 
-                         * last byte is 0. This way we can use string
-                         * manipulaton functions on call information.
-                         */
-
-			case 'd':	/* destination address */
-				for (i = 0; i < (MAX_X25_ADDR_SIZE-2); ++i){
-					ch = str[2+i];
-					if (isspace(ch)) break;
-					info->dest[i] = ch;
-				}
-				break;
-
-			case 's':	/* source address */
-				for (i = 0; i < (MAX_X25_ADDR_SIZE-2); ++i){
-					ch = str[2+i];
-					if (isspace(ch)) break;
-					info->src[i] = ch;
-				}
-				break;
-
-			case 'u':	/* user data */
-				for (i = 0; i < (MAX_X25_DATA_SIZE-2); ++i){
-					ch = str[2+i];
-					if (isspace(ch)) break;
-					info->user[i] = ch; 
-				}
-				info->nuser = i;
-				break;
-
-			case 'f':	/* facilities */
-				for (i = 0; i < (MAX_X25_FACL_SIZE-2); ++i){
-					ch = str[2+i];
-					if (isspace(ch)) break;
-					info->facil[i] = ch;
-				}
-				info->nfacil = i;
-				break;
-		}
-	}
-}
-
-/*
- * 	Convert line speed in bps to a number used by S502 code.
- */
-
-static unsigned char bps_to_speed_code (unsigned long bps)
-{
-	unsigned char	number;
-
-	if (bps <= 1200)        number = 0x01;
-	else if (bps <= 2400)   number = 0x02;
-	else if (bps <= 4800)   number = 0x03;
-	else if (bps <= 9600)   number = 0x04;
-	else if (bps <= 19200)  number = 0x05;
-	else if (bps <= 38400)  number = 0x06;
-	else if (bps <= 45000)  number = 0x07;
-	else if (bps <= 56000)  number = 0x08;
-	else if (bps <= 64000)  number = 0x09;
-	else if (bps <= 74000)  number = 0x0A;
-	else if (bps <= 112000) number = 0x0B;
-	else if (bps <= 128000) number = 0x0C;
-	else number = 0x0D;
-
-	return number;
-}
-
-/*
- * 	Convert decimal string to unsigned integer.
- * 	If len != 0 then only 'len' characters of the string are converted.
- */
-
-static unsigned int dec_to_uint (unsigned char* str, int len)
-{
-	unsigned val;
-
-	if (!len) 
-		len = strlen(str);
-
-	for (val = 0; len && isdigit(*str); ++str, --len)
-		val = (val * 10) + (*str - (unsigned)'0');
-	
-	return val;
-}
-
-/*
- * 	Convert hex string to unsigned integer.
- * 	If len != 0 then only 'len' characters of the string are conferted.
- */
-
-static unsigned int hex_to_uint (unsigned char* str, int len)
-{
-	unsigned val, ch;
-
-	if (!len) 
-		len = strlen(str);
-
-	for (val = 0; len; ++str, --len)
-	{
-		ch = *str;
-		if (isdigit(ch))
-			val = (val << 4) + (ch - (unsigned)'0');
-		else if (isxdigit(ch))
-			val = (val << 4) + ((ch & 0xDF) - (unsigned)'A' + 10);
-		else break;
-	}
-	return val;
-}
-
-
-static int handle_IPXWAN(unsigned char *sendpacket, char *devname, unsigned char enable_IPX, unsigned long network_number, unsigned short proto)
-{
-	int i;
-
-	if( proto == ETH_P_IPX) {
-		/* It's an IPX packet */
-		if(!enable_IPX) {
-			/* Return 1 so we don't pass it up the stack. */
-			return 1;
-		}
-	} else {
-		/* It's not IPX so pass it up the stack.*/ 
-		return 0;
-	}
-
-	if( sendpacket[16] == 0x90 &&
-	    sendpacket[17] == 0x04)
-	{
-		/* It's IPXWAN  */
-
-		if( sendpacket[2] == 0x02 &&
-		    sendpacket[34] == 0x00)
-		{
-			/* It's a timer request packet */
-			printk(KERN_INFO "%s: Received IPXWAN Timer Request packet\n",devname);
-
-			/* Go through the routing options and answer no to every
-			 * option except Unnumbered RIP/SAP
-			 */
-			for(i = 41; sendpacket[i] == 0x00; i += 5)
-			{
-				/* 0x02 is the option for Unnumbered RIP/SAP */
-				if( sendpacket[i + 4] != 0x02)
-				{
-					sendpacket[i + 1] = 0;
-				}
-			}
-
-			/* Skip over the extended Node ID option */
-			if( sendpacket[i] == 0x04 )
-			{
-				i += 8;
-			}
-
-			/* We also want to turn off all header compression opt. 			 */ 
-			for(; sendpacket[i] == 0x80 ;)
-			{
-				sendpacket[i + 1] = 0;
-				i += (sendpacket[i + 2] << 8) + (sendpacket[i + 3]) + 4;
-			}
-
-			/* Set the packet type to timer response */
-			sendpacket[34] = 0x01;
-
-			printk(KERN_INFO "%s: Sending IPXWAN Timer Response\n",devname);
-		}
-		else if( sendpacket[34] == 0x02 )
-		{
-			/* This is an information request packet */
-			printk(KERN_INFO "%s: Received IPXWAN Information Request packet\n",devname);
-
-			/* Set the packet type to information response */
-			sendpacket[34] = 0x03;
-
-			/* Set the router name */
-			sendpacket[51] = 'X';
-			sendpacket[52] = 'T';
-			sendpacket[53] = 'P';
-			sendpacket[54] = 'I';
-			sendpacket[55] = 'P';
-			sendpacket[56] = 'E';
-			sendpacket[57] = '-';
-			sendpacket[58] = CVHexToAscii(network_number >> 28);
-			sendpacket[59] = CVHexToAscii((network_number & 0x0F000000)>> 24);
-			sendpacket[60] = CVHexToAscii((network_number & 0x00F00000)>> 20);
-			sendpacket[61] = CVHexToAscii((network_number & 0x000F0000)>> 16);
-			sendpacket[62] = CVHexToAscii((network_number & 0x0000F000)>> 12);
-			sendpacket[63] = CVHexToAscii((network_number & 0x00000F00)>> 8);
-			sendpacket[64] = CVHexToAscii((network_number & 0x000000F0)>> 4);
-			sendpacket[65] = CVHexToAscii(network_number & 0x0000000F);
-			for(i = 66; i < 99; i+= 1)
-			{
-				sendpacket[i] = 0;
-			}
-
-			printk(KERN_INFO "%s: Sending IPXWAN Information Response packet\n",devname);
-		}
-		else
-		{
-			printk(KERN_INFO "%s: Unknown IPXWAN packet!\n",devname);
-			return 0;
-		}
-
-		/* Set the WNodeID to our network address */
-		sendpacket[35] = (unsigned char)(network_number >> 24);
-		sendpacket[36] = (unsigned char)((network_number & 0x00FF0000) >> 16);
-		sendpacket[37] = (unsigned char)((network_number & 0x0000FF00) >> 8);
-		sendpacket[38] = (unsigned char)(network_number & 0x000000FF);
-
-		return 1;
-	} else {
-		/*If we get here it's an IPX-data packet, so it'll get passed up the stack.
-		 */
-		/* switch the network numbers */
-		switch_net_numbers(sendpacket, network_number, 1);	
-		return 0;
-	}
-}
-
-/*
- *  	If incoming is 0 (outgoing)- if the net numbers is ours make it 0
- *  	if incoming is 1 - if the net number is 0 make it ours 
- */
-
-static void switch_net_numbers(unsigned char *sendpacket, unsigned long network_number, unsigned char incoming)
-{
-	unsigned long pnetwork_number;
-
-	pnetwork_number = (unsigned long)((sendpacket[6] << 24) + 
-			  (sendpacket[7] << 16) + (sendpacket[8] << 8) + 
-			  sendpacket[9]);
-	
-
-	if (!incoming) {
-		/*If the destination network number is ours, make it 0 */
-		if( pnetwork_number == network_number) {
-			sendpacket[6] = sendpacket[7] = sendpacket[8] = 
-					 sendpacket[9] = 0x00;
-		}
-	} else {
-		/* If the incoming network is 0, make it ours */
-		if( pnetwork_number == 0) {
-			sendpacket[6] = (unsigned char)(network_number >> 24);
-			sendpacket[7] = (unsigned char)((network_number & 
-					 0x00FF0000) >> 16);
-			sendpacket[8] = (unsigned char)((network_number & 
-					 0x0000FF00) >> 8);
-			sendpacket[9] = (unsigned char)(network_number & 
-					 0x000000FF);
-		}
-	}
-
-
-	pnetwork_number = (unsigned long)((sendpacket[18] << 24) + 
-			  (sendpacket[19] << 16) + (sendpacket[20] << 8) + 
-			  sendpacket[21]);
-	
-	
-	if( !incoming ) {
-		/* If the source network is ours, make it 0 */
-		if( pnetwork_number == network_number) {
-			sendpacket[18] = sendpacket[19] = sendpacket[20] = 
-				 sendpacket[21] = 0x00;
-		}
-	} else {
-		/* If the source network is 0, make it ours */
-		if( pnetwork_number == 0 ) {
-			sendpacket[18] = (unsigned char)(network_number >> 24);
-			sendpacket[19] = (unsigned char)((network_number & 
-					 0x00FF0000) >> 16);
-			sendpacket[20] = (unsigned char)((network_number & 
-					 0x0000FF00) >> 8);
-			sendpacket[21] = (unsigned char)(network_number & 
-					 0x000000FF);
-		}
-	}
-} /* switch_net_numbers */
-
-
-
-
-/********************* X25API SPECIFIC FUNCTIONS ****************/
-
-
-/*===============================================================
- *  find_channel
- *
- *	Manages the lcn to device map. It increases performance
- *      because it eliminates the need to search through the link  
- *      list for a device which is bounded to a specific lcn.
- *
- *===============================================================*/
-
-
-struct net_device *find_channel(sdla_t *card, unsigned lcn)
-{
-	if (card->u.x.LAPB_hdlc){
-
-		return card->wandev.dev;
-
-	}else{
-		/* We don't know whether the incoming lcn
-                 * is a PVC or an SVC channel. But we do know that
-                 * the lcn cannot be for both the PVC and the SVC
-                 * channel.
-
-		 * If the lcn number is greater or equal to 255, 
-                 * take the modulo 255 of that number. We only have
-                 * 255 locations, thus higher numbers must be mapped
-                 * to a number between 0 and 245. 
-
-		 * We must separate pvc's and svc's since two don't
-                 * have to be contiguous.  Meaning pvc's can start
-                 * from 1 to 10 and svc's can start from 256 to 266.
-                 * But 256%255 is 1, i.e. CONFLICT.
-		 */
-
-
-		/* Highest LCN number must be less or equal to 4096 */
-		if ((lcn <= MAX_LCN_NUM) && (lcn > 0)){
-
-			if (lcn < X25_MAX_CHAN){
-				if (card->u.x.svc_to_dev_map[lcn])
-					return card->u.x.svc_to_dev_map[lcn];
-
-				if (card->u.x.pvc_to_dev_map[lcn])
-					return card->u.x.pvc_to_dev_map[lcn];
-			
-			}else{
-				int new_lcn = lcn%X25_MAX_CHAN;
-				if (card->u.x.svc_to_dev_map[new_lcn])
-					return card->u.x.svc_to_dev_map[new_lcn];
-
-				if (card->u.x.pvc_to_dev_map[new_lcn])
-					return card->u.x.pvc_to_dev_map[new_lcn];
-			}
-		}
-		return NULL;
-	}
-}
-
-void bind_lcn_to_dev(sdla_t *card, struct net_device *dev, unsigned lcn)
-{
-	x25_channel_t *chan = dev->priv;
-
-	/* Modulo the lcn number by X25_MAX_CHAN (255)
-	 * because the lcn number can be greater than 255 
-         *
-	 * We need to split svc and pvc since they don't have
-         * to be contigous. 
-	 */
-
-	if (chan->common.svc){
-		card->u.x.svc_to_dev_map[(lcn % X25_MAX_CHAN)] = dev;
-	}else{
-		card->u.x.pvc_to_dev_map[(lcn % X25_MAX_CHAN)] = dev;
-	}
-	chan->common.lcn = lcn;
-}
-
-
-
-/*===============================================================
- * x25api_bh 
- *
- *
- *==============================================================*/
-
-static void x25api_bh(struct net_device* dev)
-{
-	x25_channel_t* chan = dev->priv;
-	sdla_t* card = chan->card;
-	struct sk_buff *skb;
-
-	if (atomic_read(&chan->bh_buff_used) == 0){
-		printk(KERN_INFO "%s: BH Buffer Empty in BH\n",
-				card->devname);
-		clear_bit(0, &chan->tq_working);
-		return;
-	}
-
-	while (atomic_read(&chan->bh_buff_used)){
-
-		/* If the sock is in the process of unlinking the
-		 * driver from the socket, we must get out. 
-		 * This never happends but is a sanity check. */
-		if (test_bit(0,&chan->common.common_critical)){
-			clear_bit(0, &chan->tq_working);
-			return;
-		}
-		
-		/* If LAPB HDLC, do not drop packets if socket is
-                 * not connected.  Let the buffer fill up and
-                 * turn off rx interrupt */
-		if (card->u.x.LAPB_hdlc){
-			if (chan->common.sk == NULL || chan->common.func == NULL){
-				clear_bit(0, &chan->tq_working);			
-				return;
-			}
-		}
-
-		skb  = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb;
-
-		if (skb == NULL){
-			printk(KERN_INFO "%s: BH Skb empty for read %i\n",
-					card->devname,chan->bh_read);
-		}else{
-			
-			if (chan->common.sk == NULL || chan->common.func == NULL){
-				printk(KERN_INFO "%s: BH: Socket disconnected, dropping\n",
-						card->devname);
-				dev_kfree_skb_any(skb);
-				x25api_bh_cleanup(dev);
-				++chan->ifstats.rx_dropped;
-				++chan->rx_intr_stat.rx_intr_bfr_not_passed_to_stack;
-				continue;
-			}
-
-
-			if (chan->common.func(skb,dev,chan->common.sk) != 0){
-				/* Sock full cannot send, queue us for another
-                                 * try 
-				 */
-				printk(KERN_INFO "%s: BH: !!! Packet failed to send !!!!! \n",
-						card->devname);
-				atomic_set(&chan->common.receive_block,1);
-				return;
-			}else{
-				x25api_bh_cleanup(dev);
-				++chan->rx_intr_stat.rx_intr_bfr_passed_to_stack;
-			}
-		}
-	}	
-	clear_bit(0, &chan->tq_working);
-
-	return;
-}
-
-/*===============================================================
- * x25api_bh_cleanup 
- *
- *
- *==============================================================*/
-
-static int x25api_bh_cleanup(struct net_device *dev)
-{
-	x25_channel_t* chan = dev->priv;
-	sdla_t *card = chan->card;
-	TX25Status* status = card->flags;
-
-
-	((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL;
-
-	if (chan->bh_read == MAX_BH_BUFF){
-		chan->bh_read=0;
-	}else{
-		++chan->bh_read;	
-	}
-
-	/* If the Receive interrupt was off, it means
-         * that we filled up our circular buffer. Check    
-         * that we have space in the buffer. If so 
-         * turn the RX interrupt back on. 
-	 */
-	if (!(status->imask & INTR_ON_RX_FRAME)){
-		if (atomic_read(&chan->bh_buff_used) < (MAX_BH_BUFF+1)){
-			printk(KERN_INFO "%s: BH: Turning on the interrupt\n",
-					card->devname);
-			status->imask |= INTR_ON_RX_FRAME;
-		}
-	}	
-
-	atomic_dec(&chan->bh_buff_used);
-	return 0;
-}
-
-
-/*===============================================================
- * bh_enqueue 
- *
- *
- *==============================================================*/
-
-static int bh_enqueue(struct net_device *dev, struct sk_buff *skb)
-{
-	x25_channel_t* chan = dev->priv;
-	sdla_t *card = chan->card;
-	TX25Status* status = card->flags;
-
-	if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){
-		printk(KERN_INFO "%s: Bottom half buffer FULL\n",
-				card->devname);
-		return 1; 
-	}
-
-	((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb;
-
-	if (chan->bh_write == MAX_BH_BUFF){
-		chan->bh_write=0;
-	}else{
-		++chan->bh_write;
-	}
-
-	atomic_inc(&chan->bh_buff_used);
-
-	if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){
-		printk(KERN_INFO "%s: Buffer is now full, Turning off RX Intr\n",
-				card->devname);
-		status->imask &= ~INTR_ON_RX_FRAME;
-	}
-
-	return 0;
-}
-
-
-/*===============================================================
- * timer_intr_cmd_exec
- *  
- *	Called by timer interrupt to execute a command
- *===============================================================*/
-
-static int timer_intr_cmd_exec (sdla_t* card)
-{
-	struct net_device *dev;
-	unsigned char more_to_exec=0;
-	volatile x25_channel_t *chan=NULL;
-	int i=0,bad_cmd=0,err=0;	
-
-	if (card->u.x.cmd_dev == NULL){
-		card->u.x.cmd_dev = card->wandev.dev;
-	}
-
-	dev = card->u.x.cmd_dev;
-
-	for (;;){
-
-		chan = dev->priv;
-		
-		if (atomic_read(&chan->common.command)){ 
-
-			bad_cmd = check_bad_command(card,dev);
-
-			if ((!chan->common.mbox || atomic_read(&chan->common.disconnect)) && 
-			     !bad_cmd){
-
-				/* Socket has died or exited, We must bring the
-                                 * channel down before anybody else tries to 
-                                 * use it */
-				err = channel_disconnect(card,dev);
-			}else{
-			        err = execute_delayed_cmd(card, dev,
-							 (mbox_cmd_t*)chan->common.mbox,
-							  bad_cmd);
-			}
-
-			switch (err){
-
-			case RETURN_RESULT:
-
-				/* Return the result to the socket without
-                                 * delay. NO_WAIT Command */	
-				atomic_set(&chan->common.command,0);
-				if (atomic_read(&card->u.x.command_busy))
-					atomic_set(&card->u.x.command_busy,0);
-
-				send_delayed_cmd_result(card,dev,card->mbox);
-
-				more_to_exec=0;
-				break;
-			case DELAY_RESULT:
-		
-				/* Wait for the remote to respond, before
-                                 * sending the result up to the socket.
-                                 * WAIT command */
-				if (atomic_read(&card->u.x.command_busy))
-					atomic_set(&card->u.x.command_busy,0);
-				
-				atomic_set(&chan->common.command,0);
-				more_to_exec=0;
-				break;
-			default:
-
-				/* If command could not be executed for
-                                 * some reason (i.e return code 0x33 busy)
-                                 * set the more_to_exec bit which will
-                                 * indicate that this command must be exectued
-                                 * again during next timer interrupt 
-				 */
-				more_to_exec=1;
-				if (atomic_read(&card->u.x.command_busy) == 0)
-					atomic_set(&card->u.x.command_busy,1);
-				break;
-			}
-
-			bad_cmd=0;
-
-			/* If flags is set, there are no hdlc buffers,
-                         * thus, wait for the next pass and try the
-                         * same command again. Otherwise, start searching 
-                         * from next device on the next pass. 
-			 */
-			if (!more_to_exec){
-				dev = move_dev_to_next(card,dev);
-			}
-			break;
-		}else{
-			/* This device has nothing to execute,
-                         * go to next. 
-			 */
-			if (atomic_read(&card->u.x.command_busy))
-					atomic_set(&card->u.x.command_busy,0);
-			dev = move_dev_to_next(card,dev);
-		}	
-
-		if (++i == card->u.x.no_dev){
-			if (!more_to_exec){
-				DBG_PRINTK(KERN_INFO "%s: Nothing to execute in Timer\n",
-					card->devname);
-				if (atomic_read(&card->u.x.command_busy)){
-					atomic_set(&card->u.x.command_busy,0);
-				}
-			}
-			break;
-		}
-
-	} //End of FOR
-
-	card->u.x.cmd_dev = dev;
-	
-	if (more_to_exec){
-		/* If more commands are pending, do not turn off timer 
-                 * interrupt */
-		return 1;
-	}else{
-		/* No more commands, turn off timer interrupt */
-		return 0;
-	}	
-}
-
-/*===============================================================
- * execute_delayed_cmd 
- *
- *	Execute an API command which was passed down from the
- *      sock.  Sock is very limited in which commands it can
- *      execute.  Wait and No Wait commands are supported.  
- *      Place Call, Clear Call and Reset wait commands, where
- *      Accept Call is a no_wait command.
- *
- *===============================================================*/
-
-static int execute_delayed_cmd(sdla_t* card, struct net_device *dev,
-			       mbox_cmd_t *usr_cmd, char bad_cmd)
-{
-	TX25Mbox* mbox = card->mbox;
-	int err;
-	x25_channel_t *chan = dev->priv;
-	int delay=RETURN_RESULT;
-
-	if (!(*card->u.x.hdlc_buf_status & 0x40) && !bad_cmd){
-		return TRY_CMD_AGAIN;
-	}
-
-	/* This way a command is guaranteed to be executed for
-         * a specific lcn, the network interface is bound to. */
-	usr_cmd->cmd.lcn = chan->common.lcn;
-	
-
-	/* If channel is pvc, instead of place call
-         * run x25_channel configuration. If running LAPB HDLC
-         * enable communications. 
-         */
-	if ((!chan->common.svc) && (usr_cmd->cmd.command == X25_PLACE_CALL)){
-
-		if (card->u.x.LAPB_hdlc){
-			DBG_PRINTK(KERN_INFO "LAPB: Connecting\n");
-			connect(card);
-			set_chan_state(dev,WAN_CONNECTING);
-			return DELAY_RESULT;
-		}else{
-			DBG_PRINTK(KERN_INFO "%s: PVC is CONNECTING\n",card->devname);
-			if (x25_get_chan_conf(card, chan) == CMD_OK){
-				set_chan_state(dev, WAN_CONNECTED);
-			}else{ 
-				set_chan_state(dev, WAN_DISCONNECTED);
-			}
-			return RETURN_RESULT;
-		}
-	}
-
-	/* Copy the socket mbox command onto the board */
-
-	memcpy(&mbox->cmd, &usr_cmd->cmd, sizeof(TX25Cmd));
-	if (usr_cmd->cmd.length){
-		memcpy(mbox->data, usr_cmd->data, usr_cmd->cmd.length);
-	}
-
-	/* Check if command is bad. We need to copy the cmd into
-         * the buffer regardless since we return the, mbox to
-         * the user */
-	if (bad_cmd){
-		mbox->cmd.result=0x01;
-		return RETURN_RESULT;
-	}
-
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-
-	if (err != CMD_OK && err != X25RES_NOT_READY)
-		x25_error(card, err, usr_cmd->cmd.command, usr_cmd->cmd.lcn);
-
-	if (mbox->cmd.result == X25RES_NOT_READY){
-		return TRY_CMD_AGAIN;
-	}
-
-	switch (mbox->cmd.command){
-
-	case X25_PLACE_CALL:
-		
-		switch (mbox->cmd.result){
-
-		case CMD_OK:
-
-			/* Check if Place call is a wait command or a 
-               	  	 * no wait command */
-			if (atomic_read(&chan->common.command) & 0x80)
- 				delay=RETURN_RESULT;
-			else
-				delay=DELAY_RESULT;
-		
-
-			DBG_PRINTK(KERN_INFO "\n%s: PLACE CALL Binding dev %s to lcn %i\n",
-					card->devname,dev->name, mbox->cmd.lcn);
-		
-			bind_lcn_to_dev (card, dev, mbox->cmd.lcn);
-			set_chan_state(dev, WAN_CONNECTING);
-			break;
-
-
-		default:
-			delay=RETURN_RESULT;
-			set_chan_state(dev, WAN_DISCONNECTED);
-			break;
-		}
-		break;
-
-	case X25_ACCEPT_CALL: 
-		
-		switch (mbox->cmd.result){
-
-		case CMD_OK:
-
-			DBG_PRINTK(KERN_INFO "\n%s: ACCEPT Binding dev %s to lcn %i\n",
-				card->devname,dev->name,mbox->cmd.lcn);
-
-			bind_lcn_to_dev (card, dev, mbox->cmd.lcn);
-
-			if (x25_get_chan_conf(card, chan) == CMD_OK){
-
-				set_chan_state(dev, WAN_CONNECTED);
-				delay=RETURN_RESULT;
-
-			}else{ 
-				if (x25_clear_call(card, usr_cmd->cmd.lcn, 0, 0) == CMD_OK){
-					/* if clear is successful, wait for clear confirm 
-					 */ 
-					delay=DELAY_RESULT;
-				}else{
-					/* Do not change the state here. If we fail 
-					 * the accept the return code is send up 
-					 *the stack, which will ether retry
-                               	  	 * or clear the call 
-					 */
-					DBG_PRINTK(KERN_INFO 
-						"%s: ACCEPT: STATE MAY BE CURRUPTED 2 !!!!!\n",
-						card->devname);
-					delay=RETURN_RESULT;
-				}
-			}
-			break;
-
-
-		case X25RES_ASYNC_PACKET:
-			delay=TRY_CMD_AGAIN;
-			break;
-
-		default: 
-			DBG_PRINTK(KERN_INFO "%s: ACCEPT FAILED\n",card->devname);
-			if (x25_clear_call(card, usr_cmd->cmd.lcn, 0, 0) == CMD_OK){
-				delay=DELAY_RESULT;
-			}else{
-				/* Do not change the state here. If we fail the accept. The
-                                 * return code is send up the stack, which will ether retry
-                                 * or clear the call */
-				DBG_PRINTK(KERN_INFO 
-					"%s: ACCEPT: STATE MAY BE CORRUPTED 1 !!!!!\n",
-						card->devname);
-				delay=RETURN_RESULT;
-			}
-		}
-		break;
-
-	case X25_CLEAR_CALL:
-
-		switch (mbox->cmd.result){
-
-		case CMD_OK:
-			DBG_PRINTK(KERN_INFO 
-					"CALL CLEAR OK: Dev %s Mbox Lcn %i  Chan Lcn %i\n",
-					dev->name,mbox->cmd.lcn,chan->common.lcn);
-			set_chan_state(dev, WAN_DISCONNECTING);
-			delay = DELAY_RESULT;
-			break;
-
-		case X25RES_CHANNEL_IN_USE:
-		case X25RES_ASYNC_PACKET:
-			delay = TRY_CMD_AGAIN;
-			break;
-			
-		case X25RES_LINK_NOT_IN_ABM:
-		case X25RES_INVAL_LCN:
-		case X25RES_INVAL_STATE:
-			set_chan_state(dev, WAN_DISCONNECTED);
-			delay = RETURN_RESULT;
-			break;
-		
-		default:
-			/* If command did not execute because of user
-                         * fault, do not change the state. This will
-                         * signal the socket that clear command failed.
-                         * User can retry or close the socket.
-                         * When socket gets killed, it will set the 
-                         * chan->disconnect which will signal
-                         * driver to clear the call */
-			printk(KERN_INFO "%s: Clear Command Failed, Rc %x\n",
-				card->devname,mbox->cmd.command); 
-			delay = RETURN_RESULT;
-		}
-		break;
-	}	
-
-	return delay;
-}
-
-/*===============================================================
- * api_incoming_call 
- *
- *	Pass an incoming call request up the listening
- *      sock.  If the API sock is not listening reject the
- *      call.
- *
- *===============================================================*/
-
-static int api_incoming_call (sdla_t* card, TX25Mbox *mbox, int lcn)
-{
-	struct sk_buff *skb;
-	int len = sizeof(TX25Cmd)+mbox->cmd.length;
-
-	if (alloc_and_init_skb_buf(card, &skb, len)){
-		printk(KERN_INFO "%s: API incoming call, no memory\n",card->devname);
-		return 1;
-	}
-
-	memcpy(skb_put(skb,len),&mbox->cmd,len);
-
-	skb->mac.raw = skb->data;
-	skb->protocol = htons(X25_PROT);
-	skb->pkt_type = WAN_PACKET_ASYNC;
-
-	if (card->func(skb,card->sk) < 0){
-		printk(KERN_INFO "%s: MAJOR ERROR: Failed to send up place call \n",card->devname);
-                dev_kfree_skb_any(skb);
-		return 1;
-	}
-
-	return 0;
-}
-
-/*===============================================================
- * send_delayed_cmd_result
- *
- *	Wait commands like PLEACE CALL or CLEAR CALL must wait
- *      until the result arrives. This function passes
- *      the result to a waiting sock. 
- *
- *===============================================================*/
-static void send_delayed_cmd_result(sdla_t *card, struct net_device *dev,
-				    TX25Mbox* mbox)
-{
-	x25_channel_t *chan = dev->priv;
-	mbox_cmd_t *usr_cmd = (mbox_cmd_t *)chan->common.mbox;
-	struct sk_buff *skb;
-	int len=sizeof(unsigned char);
-
-	atomic_set(&chan->common.command,0);
-
-	/* If the sock is in the process of unlinking the
-	 * driver from the socket, we must get out. 
-	 * This never happends but is a sanity check. */
-	if (test_bit(0,&chan->common.common_critical)){
-		return;
-	}
-
-	if (!usr_cmd || !chan->common.sk || !chan->common.func){
-		DBG_PRINTK(KERN_INFO "Delay result: Sock not bounded sk: %u, func: %u, mbox: %u\n",
-			(unsigned int)chan->common.sk,
-			(unsigned int)chan->common.func,
-			(unsigned int)usr_cmd); 
-		return;
-	}
-
-	memcpy(&usr_cmd->cmd, &mbox->cmd, sizeof(TX25Cmd)); 
-	if (mbox->cmd.length > 0){
-		memcpy(usr_cmd->data, mbox->data, mbox->cmd.length);
-	}
-
-	if (alloc_and_init_skb_buf(card,&skb,len)){
-		printk(KERN_INFO "Delay result: No sock buffers\n");
-		return;
-	}
-
-	memcpy(skb_put(skb,len),&mbox->cmd.command,len);
-	
-	skb->mac.raw = skb->data;
-	skb->pkt_type = WAN_PACKET_CMD;
-			
-	chan->common.func(skb,dev,chan->common.sk);
-}
-
-/*===============================================================
- * clear_confirm_event
- *
- * 	Pass the clear confirmation event up the sock. The
- *      API will disconnect only after the clear confirmation
- *      has been received. 
- *
- *      Depending on the state, clear confirmation could 
- *      be an OOB event, or a result of an API command.
- *===============================================================*/
-
-static int clear_confirm_event (sdla_t *card, TX25Mbox* mb)
-{
-	struct net_device *dev;
-	x25_channel_t *chan;
-	unsigned char old_state;	
-
-	dev = find_channel(card,mb->cmd.lcn);
-	if (!dev){
-		DBG_PRINTK(KERN_INFO "%s: *** GOT CLEAR BUT NO DEV %i\n",
-				card->devname,mb->cmd.lcn);
-		return 0;
-	}
-
-	chan=dev->priv;
-	DBG_PRINTK(KERN_INFO "%s: GOT CLEAR CONFIRM %s:  Mbox lcn %i  Chan lcn %i\n",
-			card->devname, dev->name, mb->cmd.lcn, chan->common.lcn);
-
-	/* If not API fall through to default. 
-	 * If API, send the result to a waiting
-         * socket.
-	 */
-	
-	old_state = chan->common.state;
-	set_chan_state(dev, WAN_DISCONNECTED);
-
-	if (chan->common.usedby == API){
-		switch (old_state) {
-
-		case WAN_DISCONNECTING:
-		case WAN_CONNECTING:
-			send_delayed_cmd_result(card,dev,mb);
-			break;
-		case WAN_CONNECTED:
-			send_oob_msg(card,dev,mb);
-			break;
-		}
-		return 1;
-	}
-
-	return 0;
-}
-
-/*===============================================================
- * send_oob_msg
- *
- *    Construct an NEM Message and pass it up the connected
- *    sock. If the sock is not bounded discard the NEM.
- *
- *===============================================================*/
-
-static void send_oob_msg(sdla_t *card, struct net_device *dev, TX25Mbox *mbox)
-{
-	x25_channel_t *chan = dev->priv;
-	mbox_cmd_t *usr_cmd = (mbox_cmd_t *)chan->common.mbox;
-	struct sk_buff *skb;
-	int len=sizeof(x25api_hdr_t)+mbox->cmd.length;
-	x25api_t *api_hdr;
-
-	/* If the sock is in the process of unlinking the
-	 * driver from the socket, we must get out. 
-	 * This never happends but is a sanity check. */
-	if (test_bit(0,&chan->common.common_critical)){
-		return;
-	}
-
-	if (!usr_cmd || !chan->common.sk || !chan->common.func){
-		DBG_PRINTK(KERN_INFO "OOB MSG: Sock not bounded\n"); 
-		return;
-	}
-
-	memcpy(&usr_cmd->cmd, &mbox->cmd, sizeof(TX25Cmd)); 
-	if (mbox->cmd.length > 0){
-		memcpy(usr_cmd->data, mbox->data, mbox->cmd.length);
-	}
-
-	if (alloc_and_init_skb_buf(card,&skb,len)){
-		printk(KERN_INFO "%s: OOB MSG: No sock buffers\n",card->devname);
-		return;
-	}
-
-	api_hdr = (x25api_t*)skb_put(skb,len); 
-	api_hdr->hdr.pktType = mbox->cmd.pktType & 0x7F;
-	api_hdr->hdr.qdm     = mbox->cmd.qdm;
-	api_hdr->hdr.cause   = mbox->cmd.cause;
-	api_hdr->hdr.diagn   = mbox->cmd.diagn;
-	api_hdr->hdr.length  = mbox->cmd.length;
-	api_hdr->hdr.result  = mbox->cmd.result;
-	api_hdr->hdr.lcn     = mbox->cmd.lcn;
-
-	if (mbox->cmd.length > 0){
-		memcpy(api_hdr->data,mbox->data,mbox->cmd.length);
-	}
-	
-	skb->mac.raw = skb->data;
-	skb->pkt_type = WAN_PACKET_ERR;
-			
-	if (chan->common.func(skb,dev,chan->common.sk) < 0){
-		if (bh_enqueue(dev,skb)){
-			printk(KERN_INFO "%s: Dropping OOB MSG\n",card->devname);
-                	dev_kfree_skb_any(skb);
-		}
-	}
-
-	DBG_PRINTK(KERN_INFO "%s: OOB MSG OK, %s, lcn %i\n",
-			card->devname, dev->name, mbox->cmd.lcn);
-}	
-
-/*===============================================================
- *  alloc_and_init_skb_buf 
- *
- *	Allocate and initialize an skb buffer. 
- *
- *===============================================================*/
-
-static int alloc_and_init_skb_buf (sdla_t *card, struct sk_buff **skb, int len)
-{
-	struct sk_buff *new_skb = *skb;
-
-	new_skb = dev_alloc_skb(len + X25_HRDHDR_SZ);
-	if (new_skb == NULL){
-		printk(KERN_INFO "%s: no socket buffers available!\n",
-			card->devname);
-		return 1;
-	}
-
-	if (skb_tailroom(new_skb) < len){
-		/* No room for the packet. Call off the whole thing! */
-                dev_kfree_skb_any(new_skb);
-		printk(KERN_INFO "%s: Listen: unexpectedly long packet sequence\n"
-			,card->devname);
-		*skb = NULL;
-		return 1;
-	}
-
-	*skb = new_skb;
-	return 0;
-
-}
-
-/*===============================================================
- *  api_oob_event 
- *
- *	Send an OOB event up to the sock 
- *
- *===============================================================*/
-
-static void api_oob_event (sdla_t *card,TX25Mbox *mbox)
-{
-	struct net_device *dev = find_channel(card, mbox->cmd.lcn);
-	x25_channel_t *chan;
-
-	if (!dev)
-		return;
-
-	chan=dev->priv;
-
-	if (chan->common.usedby == API)
-		send_oob_msg(card,dev,mbox);
-	
-}
-
-
-
-
-static int channel_disconnect(sdla_t* card, struct net_device *dev)
-{
-
-	int err;
-	x25_channel_t *chan = dev->priv;
-
-	DBG_PRINTK(KERN_INFO "%s: TIMER: %s, Device down disconnecting\n",
-				card->devname,dev->name);
-
-	if (chan->common.svc){
-		err = x25_clear_call(card,chan->common.lcn,0,0);
-	}else{
-		/* If channel is PVC or LAPB HDLC, there is no call
-                 * to be cleared, thus drop down to the default
-                 * area 
-	         */
-		err = 1;
-	}
-
-	switch (err){
-	
-		case X25RES_CHANNEL_IN_USE:	
-		case X25RES_NOT_READY:
-			err = TRY_CMD_AGAIN;
-			break;
-		case CMD_OK:
-			DBG_PRINTK(KERN_INFO "CALL CLEAR OK: Dev %s Chan Lcn %i\n",
-						dev->name,chan->common.lcn);
-
-			set_chan_state(dev,WAN_DISCONNECTING);
-			atomic_set(&chan->common.command,0);
-			err = DELAY_RESULT;
-			break;
-		default:
-			/* If LAPB HDLC protocol, bring the whole link down
-                         * once the application terminates 
-			 */
-
-			set_chan_state(dev,WAN_DISCONNECTED);
-
-			if (card->u.x.LAPB_hdlc){
-				DBG_PRINTK(KERN_INFO "LAPB: Disconnecting Link\n");
-				hdlc_link_down (card);
-			}
-			atomic_set(&chan->common.command,0);
-			err = RETURN_RESULT;
-			break;
-	}
-
-	return err;
-}
-
-static void hdlc_link_down (sdla_t *card)
-{
-	TX25Mbox* mbox = card->mbox;
-	int retry = 5;
-	int err=0;
-
-	do {
-		memset(mbox,0,sizeof(TX25Mbox));
-		mbox->cmd.command = X25_HDLC_LINK_DISC;
-		mbox->cmd.length = 1;
-		mbox->data[0]=0;
-		err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-
-	} while (err && retry-- && x25_error(card, err, X25_HDLC_LINK_DISC, 0));
-
-	if (err)
-		printk(KERN_INFO "%s: Hdlc Link Down Failed %x\n",card->devname,err);
-
-	disconnect (card);
-	
-}
-
-static int check_bad_command(sdla_t* card, struct net_device *dev)
-{
-	x25_channel_t *chan = dev->priv;
-	int bad_cmd = 0;
-
-	switch (atomic_read(&chan->common.command)&0x7F){
-
-		case X25_PLACE_CALL:
-			if (chan->common.state != WAN_DISCONNECTED)
-				bad_cmd=1;
-			break;
-		case X25_CLEAR_CALL:
-			if (chan->common.state == WAN_DISCONNECTED)
-				bad_cmd=1;
-			break;
-		case X25_ACCEPT_CALL:
-			if (chan->common.state != WAN_CONNECTING)
-				bad_cmd=1;
-			break;
-		case X25_RESET:
-			if (chan->common.state != WAN_CONNECTED)
-				bad_cmd=1;
-			break;
-		default:
-			bad_cmd=1;
-			break;
-	}
-
-	if (bad_cmd){
-		printk(KERN_INFO "%s: Invalid State, BAD Command %x, dev %s, lcn %i, st %i\n", 
-			card->devname,atomic_read(&chan->common.command),dev->name, 
-			chan->common.lcn, chan->common.state);
-	}
-
-	return bad_cmd;
-}
-
-
-
-/*************************** XPIPEMON FUNCTIONS **************************/
-
-/*==============================================================================
- * Process UDP call of type XPIPE
- */
-
-static int process_udp_mgmt_pkt(sdla_t *card)
-{
-	int            c_retry = MAX_CMD_RETRY;
-	unsigned int   len;
-	struct sk_buff *new_skb;
-	TX25Mbox       *mbox = card->mbox;
-	int            err;
-	int            udp_mgmt_req_valid = 1;
-	struct net_device *dev;
-        x25_channel_t  *chan;
-	unsigned short lcn;
-	struct timeval tv;
-	
-
-	x25_udp_pkt_t *x25_udp_pkt;
-	x25_udp_pkt = (x25_udp_pkt_t *)card->u.x.udp_pkt_data;
-
-	dev = card->u.x.udp_dev;
-	chan = dev->priv;
-	lcn = chan->common.lcn;
-
-	switch(x25_udp_pkt->cblock.command) {
-            
-		/* XPIPE_ENABLE_TRACE */
-		case XPIPE_ENABLE_TRACING:
-
-		/* XPIPE_GET_TRACE_INFO */
-		case XPIPE_GET_TRACE_INFO:
- 
-		/* SET FT1 MODE */
-		case XPIPE_SET_FT1_MODE:
-           
-			if(card->u.x.udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-                    		++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_direction_err;
-				udp_mgmt_req_valid = 0;
-				break;
-			}
-
-		/* XPIPE_FT1_READ_STATUS */
-		case XPIPE_FT1_READ_STATUS:
-
-		/* FT1 MONITOR STATUS */
-		case XPIPE_FT1_STATUS_CTRL:
-			if(card->hw.fwid !=  SFID_X25_508) {
-				++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_type_err;
-				udp_mgmt_req_valid = 0;
-				break;
-			}
-		default:
-			break;
-       	}
-
-	if(!udp_mgmt_req_valid) {
-           	/* set length to 0 */
-		x25_udp_pkt->cblock.length = 0;
-		/* set return code */
-		x25_udp_pkt->cblock.result = (card->hw.fwid != SFID_X25_508) ? 0x1F : 0xCD;
-		
-	} else {   
-        
-		switch (x25_udp_pkt->cblock.command) {
-    
-	
-		case XPIPE_FLUSH_DRIVER_STATS:
-			init_x25_channel_struct(chan);
-			init_global_statistics(card);
-			mbox->cmd.length = 0;
-			break;
-
-
-		case XPIPE_DRIVER_STAT_IFSEND:
-			memcpy(x25_udp_pkt->data, &chan->if_send_stat, sizeof(if_send_stat_t));
-			mbox->cmd.length = sizeof(if_send_stat_t);
-			x25_udp_pkt->cblock.length =  mbox->cmd.length;	
-			break;
-	
-		case XPIPE_DRIVER_STAT_INTR:
-			memcpy(&x25_udp_pkt->data[0], &card->statistics, sizeof(global_stats_t));
-                        memcpy(&x25_udp_pkt->data[sizeof(global_stats_t)],
-                                &chan->rx_intr_stat, sizeof(rx_intr_stat_t));
-			
-			mbox->cmd.length = sizeof(global_stats_t) +
-					sizeof(rx_intr_stat_t);
-			x25_udp_pkt->cblock.length =  mbox->cmd.length;
-			break;
-
-		case XPIPE_DRIVER_STAT_GEN:
-                        memcpy(x25_udp_pkt->data,
-                                &chan->pipe_mgmt_stat.UDP_PIPE_mgmt_kmalloc_err,
-                                sizeof(pipe_mgmt_stat_t));
-
-                        memcpy(&x25_udp_pkt->data[sizeof(pipe_mgmt_stat_t)],
-                               &card->statistics, sizeof(global_stats_t));
-
-                        x25_udp_pkt->cblock.result = 0;
-                        x25_udp_pkt->cblock.length = sizeof(global_stats_t)+
-                                                     sizeof(rx_intr_stat_t);
-                        mbox->cmd.length = x25_udp_pkt->cblock.length;
-                        break;
-
-		case XPIPE_ROUTER_UP_TIME:
-			do_gettimeofday(&tv);
-			chan->router_up_time = tv.tv_sec - chan->router_start_time;
-    	                *(unsigned long *)&x25_udp_pkt->data = chan->router_up_time;	
-			x25_udp_pkt->cblock.length = mbox->cmd.length = 4;
-			x25_udp_pkt->cblock.result = 0;
-			break;
-	
-		default :
-
-			do {
-				memcpy(&mbox->cmd, &x25_udp_pkt->cblock.command, sizeof(TX25Cmd));
-				if(mbox->cmd.length){ 
-					memcpy(&mbox->data, 
-					       (char *)x25_udp_pkt->data, 
-					       mbox->cmd.length);
-				}	
-		
-				err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-			} while (err && c_retry-- && x25_error(card, err, mbox->cmd.command, 0));
-
-
-			if ( err == CMD_OK || 
-			    (err == 1 && 
-			     (mbox->cmd.command == 0x06 || 
-			      mbox->cmd.command == 0x16)  ) ){
-
-				++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_cmnd_OK;
-			} else {
-				++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_cmnd_timeout;
-			}
-
-			  /* copy the result back to our buffer */
-			memcpy(&x25_udp_pkt->cblock.command, &mbox->cmd, sizeof(TX25Cmd));
-
-      	         	if(mbox->cmd.length) {
-        	               memcpy(&x25_udp_pkt->data, &mbox->data, mbox->cmd.length);
-			}
-			break;
-
-		} //switch
-
-        }
-    
-        /* Fill UDP TTL */
-
-	x25_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
-        len = reply_udp(card->u.x.udp_pkt_data, mbox->cmd.length);
-
-
-        if(card->u.x.udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-		
-		err = x25_send(card, lcn, 0, len, card->u.x.udp_pkt_data);
-		if (!err) 
-			++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_send_passed;
-		else
-			++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_adptr_send_failed;
-	
-	} else {
-
-		/* Allocate socket buffer */
-		if((new_skb = dev_alloc_skb(len)) != NULL) {
-			void *buf;
-
-			/* copy data into new_skb */
-			buf = skb_put(new_skb, len);
-			memcpy(buf, card->u.x.udp_pkt_data, len);
-        
-			/* Decapsulate packet and pass it up the protocol 
-			   stack */
-			new_skb->dev = dev;
-	
-			if (chan->common.usedby == API)
-                        	new_skb->protocol = htons(X25_PROT);
-			else 
-				new_skb->protocol = htons(ETH_P_IP);
-	
-                        new_skb->mac.raw = new_skb->data;
-
-			netif_rx(new_skb);
-			++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_passed_to_stack;
-            	
-		} else {
-			++chan->pipe_mgmt_stat.UDP_PIPE_mgmt_no_socket;
-			printk(KERN_INFO 
-			"%s: UDP mgmt cmnd, no socket buffers available!\n", 
-			card->devname);
-            	}
-        }
-
-	card->u.x.udp_pkt_lgth = 0;
-
-	return 1;
-}
-
-
-/*==============================================================================
- * Determine what type of UDP call it is. DRVSTATS or XPIPE8ND ?
- */
-static int udp_pkt_type( struct sk_buff *skb, sdla_t* card )
-{
-	x25_udp_pkt_t *x25_udp_pkt = (x25_udp_pkt_t *)skb->data;
-
-        if((x25_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
-		(x25_udp_pkt->ip_pkt.ver_inet_hdr_length == 0x45) &&
-		(x25_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
-		(x25_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
-
-                        if(!strncmp(x25_udp_pkt->wp_mgmt.signature,
-                                UDPMGMT_XPIPE_SIGNATURE, 8)){
-                                return UDP_XPIPE_TYPE;
-			}else{
-				printk(KERN_INFO "%s: UDP Packet, Failed Signature !\n",
-					card->devname);
-			}
-	}
-
-        return UDP_INVALID_TYPE;
-}
-
-
-/*============================================================================
- * Reply to UDP Management system.
- * Return nothing.
- */
-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;
-
-  
-	x25_udp_pkt_t *x25_udp_pkt = (x25_udp_pkt_t *)data; 
-
-	/* Set length of packet */
-	len = sizeof(ip_pkt_t)+ 
-	      sizeof(udp_pkt_t)+
-	      sizeof(wp_mgmt_t)+
-	      sizeof(cblock_t)+
-	      mbox_len;
- 
-
-	/* fill in UDP reply */
-	x25_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)+
-		     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);
-	x25_udp_pkt->udp_pkt.udp_length = temp;
-	 
-	/* swap UDP ports */
-	temp = x25_udp_pkt->udp_pkt.udp_src_port;
-	x25_udp_pkt->udp_pkt.udp_src_port = 
-			x25_udp_pkt->udp_pkt.udp_dst_port; 
-	x25_udp_pkt->udp_pkt.udp_dst_port = temp;
-
-
-
-	/* add UDP pseudo header */
-	temp = 0x1100;
-	*((unsigned short *)
-		(x25_udp_pkt->data+mbox_len+even_bound)) = temp;	
-	temp = (udp_length<<8)|(udp_length>>8);
-	*((unsigned short *)
-		(x25_udp_pkt->data+mbox_len+even_bound+2)) = temp;
-		 
-	/* calculate UDP checksum */
-	x25_udp_pkt->udp_pkt.udp_checksum = 0;
-
-	x25_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);
-	x25_udp_pkt->ip_pkt.total_length = temp;
-  
-	/* swap IP addresses */
-	ip_temp = x25_udp_pkt->ip_pkt.ip_src_address;
-	x25_udp_pkt->ip_pkt.ip_src_address = 
-				x25_udp_pkt->ip_pkt.ip_dst_address;
-	x25_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
-
-		 
-	/* fill in IP checksum */
-	x25_udp_pkt->ip_pkt.hdr_checksum = 0;
-	x25_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;	
-}
-
-/*=============================================================================
- * Store a UDP management packet for later processing.
- */
-
-static int store_udp_mgmt_pkt(int udp_type, char udp_pkt_src, sdla_t* card,
-			      struct net_device *dev, struct sk_buff *skb,
-			      int lcn)
-{
-        int udp_pkt_stored = 0;
-
-        if(!card->u.x.udp_pkt_lgth && (skb->len <= MAX_LGTH_UDP_MGNT_PKT)){
-                card->u.x.udp_pkt_lgth = skb->len;
-                card->u.x.udp_type = udp_type;
-                card->u.x.udp_pkt_src = udp_pkt_src;
-                card->u.x.udp_lcn = lcn;
-		card->u.x.udp_dev = dev;
-                memcpy(card->u.x.udp_pkt_data, skb->data, skb->len);
-                card->u.x.timer_int_enabled |= TMR_INT_ENABLED_UDP_PKT;
-                udp_pkt_stored = 1;
-
-        }else{
-                printk(KERN_INFO "%s: ERROR: UDP packet not stored for LCN %d\n", 
-							card->devname,lcn);
-	}
-
-        if(udp_pkt_src == UDP_PKT_FRM_STACK){
-                dev_kfree_skb_any(skb);
-	}else{
-                dev_kfree_skb_any(skb);
-	}
-
-        return(udp_pkt_stored);
-}
-
-
-
-/*=============================================================================
- * Initial the ppp_private_area structure.
- */
-static void init_x25_channel_struct( x25_channel_t *chan )
-{
-	memset(&chan->if_send_stat.if_send_entry,0,sizeof(if_send_stat_t));
-	memset(&chan->rx_intr_stat.rx_intr_no_socket,0,sizeof(rx_intr_stat_t));
-	memset(&chan->pipe_mgmt_stat.UDP_PIPE_mgmt_kmalloc_err,0,sizeof(pipe_mgmt_stat_t));
-}
-
-/*============================================================================
- * Initialize Global Statistics
- */
-static void init_global_statistics( sdla_t *card )
-{
-	memset(&card->statistics.isr_entry,0,sizeof(global_stats_t));
-}
-
-
-/*===============================================================
- * SMP Support
- * ==============================================================*/
-
-static void S508_S514_lock(sdla_t *card, unsigned long *smp_flags)
-{
-	spin_lock_irqsave(&card->wandev.lock, *smp_flags);
-}
-static void S508_S514_unlock(sdla_t *card, unsigned long *smp_flags)
-{
-	spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
-}
-
-/*===============================================================
- * x25_timer_routine
- *
- * 	A more efficient polling routine.  Each half a second
- * 	queue a polling task. We want to do the polling in a 
- * 	task not timer, because timer runs in interrupt time.
- *
- * 	FIXME Polling should be rethinked.
- *==============================================================*/
-
-static void x25_timer_routine(unsigned long data)
-{
-	sdla_t *card = (sdla_t*)data;
-
-	if (!card->wandev.dev){
-		printk(KERN_INFO "%s: Stopping the X25 Poll Timer: No Dev.\n",
-				card->devname);
-		return;
-	}
-
-	if (card->open_cnt != card->u.x.num_of_ch){
-		printk(KERN_INFO "%s: Stopping the X25 Poll Timer: Interface down.\n",
-				card->devname);
-		return;
-	}
-
-	if (test_bit(PERI_CRIT,&card->wandev.critical)){
-		printk(KERN_INFO "%s: Stopping the X25 Poll Timer: Shutting down.\n",
-				card->devname);
-		return;
-	}
-	
-	if (!test_and_set_bit(POLL_CRIT,&card->wandev.critical)){
-		trigger_x25_poll(card);
-	}
-	
-	card->u.x.x25_timer.expires=jiffies+(HZ>>1);
-	add_timer(&card->u.x.x25_timer);
-	return;
-}
-
-void disable_comm_shutdown(sdla_t *card)
-{
-	TX25Mbox* mbox = card->mbox;
-	int err;
-
-	/* Turn of interrutps */
-	mbox->data[0] = 0;
-	if (card->hw.fwid == SFID_X25_508){
-		mbox->data[1] = card->hw.irq;
-		mbox->data[2] = 2;
-		mbox->cmd.length = 3;
-	}else {
-	 	mbox->cmd.length  = 1;
-	}
-	mbox->cmd.command = X25_SET_INTERRUPT_MODE;
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	if (err)
-		printk(KERN_INFO "INTERRUPT OFF FAIED %x\n",err);
-
-	/* Bring down HDLC */
-	mbox->cmd.command = X25_HDLC_LINK_CLOSE;
-	mbox->cmd.length  = 0;
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	if (err)
-		printk(KERN_INFO "LINK CLOSED FAILED %x\n",err);
-
-
-	/* Brind down DTR */
-	mbox->data[0] = 0;
-	mbox->data[2] = 0;
-	mbox->data[1] = 0x01;
-	mbox->cmd.length  = 3;
-	mbox->cmd.command = X25_SET_GLOBAL_VARS;
-	err = sdla_exec(mbox) ? mbox->cmd.result : CMD_TIMEOUT;
-	if (err)
-		printk(KERN_INFO "DTR DOWN FAILED %x\n",err);
-
-}
-
-MODULE_LICENSE("GPL");
-
-/****** End *****************************************************************/
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
deleted file mode 100644
index 032c0f8..0000000
--- a/drivers/net/wan/sdladrv.c
+++ /dev/null
@@ -1,2314 +0,0 @@
-/*****************************************************************************
-* sdladrv.c	SDLA Support Module.  Main module.
-*
-*		This module is a library of common hardware-specific functions
-*		used by all Sangoma drivers.
-*
-* Author:	Gideon Hack	
-*
-* Copyright:	(c) 1995-2000 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 20, 2001  Nenad Corbic	Added the auto_pci_cfg filed, to support
-*                               the PCISLOT #0. 
-* Apr 04, 2000  Nenad Corbic	Fixed the auto memory detection code.
-*                               The memory test at address 0xC8000.
-* Mar 09, 2000  Nenad Corbic 	Added Gideon's Bug Fix: clear pci
-*                               interrupt flags on initial load.
-* Jun 02, 1999  Gideon Hack     Added support for the S514 adapter.
-*				Updates for Linux 2.2.X kernels.	
-* Sep 17, 1998	Jaspreet Singh	Updates for linux 2.2.X kernels
-* Dec 20, 1996	Gene Kozin	Version 3.0.0. Complete overhaul.
-* Jul 12, 1996	Gene Kozin	Changes for Linux 2.0 compatibility.
-* Jun 12, 1996	Gene Kozin 	Added support for S503 card.
-* Apr 30, 1996	Gene Kozin	SDLA hardware interrupt is acknowledged before
-*				calling protocolspecific ISR.
-*				Register I/O ports with Linux kernel.
-*				Miscellaneous bug fixes.
-* Dec 20, 1995	Gene Kozin	Fixed a bug in interrupt routine.
-* Oct 14, 1995	Gene Kozin	Initial version.
-*****************************************************************************/
-
-/*****************************************************************************
- * Notes:
- * ------
- * 1. This code is ment to be system-independent (as much as possible).  To
- *    achive this, various macros are used to hide system-specific interfaces.
- *    To compile this code, one of the following constants must be defined:
- *
- *	Platform	Define
- *	--------	------
- *	Linux		_LINUX_
- *	SCO Unix	_SCO_UNIX_
- *
- * 2. Supported adapter types:
- *
- *	S502A
- *	ES502A (S502E)
- *	S503
- *	S507
- *	S508 (S509)
- *
- * 3. S502A Notes:
- *
- *	There is no separate DPM window enable/disable control in S502A.  It
- *	opens immediately after a window number it written to the HMCR
- *	register.  To close the window, HMCR has to be written a value
- *	????1111b (e.g. 0x0F or 0xFF).
- *
- *	S502A DPM window cannot be located at offset E000 (e.g. 0xAE000).
- *
- *	There should be a delay of ??? before reading back S502A status
- *	register.
- *
- * 4. S502E Notes:
- *
- *	S502E has a h/w bug: although default IRQ line state is HIGH, enabling
- *	interrupts by setting bit 1 of the control register (BASE) to '1'
- *	causes it to go LOW! Therefore, disabling interrupts by setting that
- *	bit to '0' causes low-to-high transition on IRQ line (ghosty
- *	interrupt). The same occurs when disabling CPU by resetting bit 0 of
- *	CPU control register (BASE+3) - see the next note.
- *
- *	S502E CPU and DPM control is limited:
- *
- *	o CPU cannot be stopped independently. Resetting bit 0 of the CPUi
- *	  control register (BASE+3) shuts the board down entirely, including
- *	  DPM;
- *
- *	o DPM access cannot be controlled dynamically. Ones CPU is started,
- *	  bit 1 of the control register (BASE) is used to enable/disable IRQ,
- *	  so that access to shared memory cannot be disabled while CPU is
- *	  running.
- ****************************************************************************/
-
-#define	_LINUX_
-
-#if	defined(_LINUX_)	/****** Linux *******************************/
-
-#include <linux/config.h>
-#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/module.h>	/* support for loadable modules */
-#include <linux/jiffies.h>	/* for jiffies, HZ, etc. */
-#include <linux/sdladrv.h>	/* API definitions */
-#include <linux/sdlasfm.h>	/* SDLA firmware module definitions */
-#include <linux/sdlapci.h>	/* SDLA PCI hardware definitions */
-#include <linux/pci.h>		/* PCI defines and function prototypes */
-#include <asm/io.h>		/* for inb(), outb(), etc. */
-
-#define _INB(port)		(inb(port))
-#define _OUTB(port, byte)	(outb((byte),(port)))
-#define	SYSTEM_TICK		jiffies
-
-#include <linux/init.h>
-
-
-#elif	defined(_SCO_UNIX_)	/****** SCO Unix ****************************/
-
-#if	!defined(INKERNEL)
-#error	This code MUST be compiled in kernel mode!
-#endif
-#include <sys/sdladrv.h>	/* API definitions */
-#include <sys/sdlasfm.h>	/* SDLA firmware module definitions */
-#include <sys/inline.h>		/* for inb(), outb(), etc. */
-#define _INB(port)		(inb(port))
-#define _OUTB(port, byte)	(outb((port),(byte)))
-#define	SYSTEM_TICK		lbolt
-
-#else
-#error	Unknown system type!
-#endif
-
-#define	MOD_VERSION	3
-#define	MOD_RELEASE	0
-
-#define	SDLA_IODELAY	100	/* I/O Rd/Wr delay, 10 works for 486DX2-66 */
-#define	EXEC_DELAY	20	/* shared memory access delay, mks */
-#define	EXEC_TIMEOUT	(HZ*2)	/* command timeout, in ticks */
-
-/* I/O port address range */
-#define S502A_IORANGE	3
-#define S502E_IORANGE	4
-#define S503_IORANGE	3
-#define S507_IORANGE	4
-#define S508_IORANGE	4
-
-/* Maximum amount of memory */
-#define S502_MAXMEM	0x10000L
-#define S503_MAXMEM	0x10000L
-#define S507_MAXMEM	0x40000L
-#define S508_MAXMEM	0x40000L
-
-/* Minimum amount of memory */
-#define S502_MINMEM	0x8000L
-#define S503_MINMEM	0x8000L
-#define S507_MINMEM	0x20000L
-#define S508_MINMEM	0x20000L
-#define NO_PORT         -1
-
-
-
-
-
-/****** Function Prototypes *************************************************/
-
-/* Hardware-specific functions */
-static int sdla_detect	(sdlahw_t* hw);
-static int sdla_autodpm	(sdlahw_t* hw);
-static int sdla_setdpm	(sdlahw_t* hw);
-static int sdla_load	(sdlahw_t* hw, sfm_t* sfm, unsigned len);
-static int sdla_init	(sdlahw_t* hw);
-static unsigned long sdla_memtest (sdlahw_t* hw);
-static int sdla_bootcfg	(sdlahw_t* hw, sfm_info_t* sfminfo);
-static unsigned char make_config_byte (sdlahw_t* hw);
-static int sdla_start	(sdlahw_t* hw, unsigned addr);
-
-static int init_s502a	(sdlahw_t* hw);
-static int init_s502e	(sdlahw_t* hw);
-static int init_s503	(sdlahw_t* hw);
-static int init_s507	(sdlahw_t* hw);
-static int init_s508	(sdlahw_t* hw);
-            
-static int detect_s502a	(int port);
-static int detect_s502e	(int port);
-static int detect_s503	(int port);
-static int detect_s507	(int port);
-static int detect_s508	(int port);
-static int detect_s514  (sdlahw_t* hw);
-static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card);
-
-/* Miscellaneous functions */
-static void peek_by_4 (unsigned long src, void* buf, unsigned len);
-static void poke_by_4 (unsigned long dest, void* buf, unsigned len);
-static int calibrate_delay (int mks);
-static int get_option_index (unsigned* optlist, unsigned optval);
-static unsigned check_memregion (void* ptr, unsigned len);
-static unsigned	test_memregion (void* ptr, unsigned len);
-static unsigned short checksum (unsigned char* buf, unsigned len);
-static int init_pci_slot(sdlahw_t *);
-
-static int pci_probe(sdlahw_t *hw);
-
-/****** Global Data **********************************************************
- * Note: All data must be explicitly initialized!!!
- */
-
-static struct pci_device_id sdladrv_pci_tbl[] = {
-	{ V3_VENDOR_ID, V3_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, },
-	{ }			/* Terminating entry */
-};
-MODULE_DEVICE_TABLE(pci, sdladrv_pci_tbl);
-
-MODULE_LICENSE("GPL");
-
-/* private data */
-static char modname[]	= "sdladrv";
-static char fullname[]	= "SDLA Support Module";
-static char copyright[]	= "(c) 1995-1999 Sangoma Technologies Inc.";
-static unsigned	exec_idle;
-
-/* Hardware configuration options.
- * These are arrays of configuration options used by verification routines.
- * The first element of each array is its size (i.e. number of options).
- */
-static unsigned	s502_port_options[] =
-	{ 4, 0x250, 0x300, 0x350, 0x360 }
-;
-static unsigned	s503_port_options[] =
-	{ 8, 0x250, 0x254, 0x300, 0x304, 0x350, 0x354, 0x360, 0x364 }
-;
-static unsigned	s508_port_options[] =
-	{ 8, 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390 }
-;
-
-static unsigned s502a_irq_options[] = { 0 };
-static unsigned s502e_irq_options[] = { 4, 2, 3, 5, 7 };
-static unsigned s503_irq_options[]  = { 5, 2, 3, 4, 5, 7 };
-static unsigned s508_irq_options[]  = { 8, 3, 4, 5, 7, 10, 11, 12, 15 };
-
-static unsigned s502a_dpmbase_options[] =
-{
-	28,
-	0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000,
-	0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000,
-	0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000,
-	0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000,
-};
-static unsigned s507_dpmbase_options[] =
-{
-	32,
-	0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
-	0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
-	0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
-	0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
-};
-static unsigned s508_dpmbase_options[] =	/* incl. S502E and S503 */
-{
-	32,
-	0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000,
-	0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
-	0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
-	0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000,
-};
-
-/*
-static unsigned	s502_dpmsize_options[] = { 2, 0x2000, 0x10000 };
-static unsigned	s507_dpmsize_options[] = { 2, 0x2000, 0x4000 };
-static unsigned	s508_dpmsize_options[] = { 1, 0x2000 };
-*/
-
-static unsigned	s502a_pclk_options[] = { 2, 3600, 7200 };
-static unsigned	s502e_pclk_options[] = { 5, 3600, 5000, 7200, 8000, 10000 };
-static unsigned	s503_pclk_options[]  = { 3, 7200, 8000, 10000 };
-static unsigned	s507_pclk_options[]  = { 1, 12288 };
-static unsigned	s508_pclk_options[]  = { 1, 16000 };
-
-/* Host memory control register masks */
-static unsigned char s502a_hmcr[] =
-{
-	0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C,	/* A0000 - AC000 */
-	0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C,	/* C0000 - CC000 */
-	0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C,	/* D0000 - DC000 */
-	0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C,	/* E0000 - EC000 */
-};
-static unsigned char s502e_hmcr[] =
-{
-	0x10, 0x12, 0x14, 0x16, 0x18, 0x1A, 0x1C, 0x1E,	/* A0000 - AE000 */
-	0x20, 0x22, 0x24, 0x26, 0x28, 0x2A, 0x2C, 0x2E,	/* C0000 - CE000 */
-	0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,	/* D0000 - DE000 */
-	0x30, 0x32, 0x34, 0x36, 0x38, 0x3A, 0x3C, 0x3E,	/* E0000 - EE000 */
-};
-static unsigned char s507_hmcr[] =
-{
-	0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0E,	/* A0000 - AE000 */
-	0x40, 0x42, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E,	/* B0000 - BE000 */
-	0x80, 0x82, 0x84, 0x86, 0x88, 0x8A, 0x8C, 0x8E,	/* C0000 - CE000 */
-	0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,	/* E0000 - EE000 */
-};
-static unsigned char s508_hmcr[] =
-{
-	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,	/* A0000 - AE000 */
-	0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,	/* C0000 - CE000 */
-	0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,	/* D0000 - DE000 */
-	0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,	/* E0000 - EE000 */
-};
-
-static unsigned char s507_irqmask[] =
-{
-	0x00, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xC0, 0xE0
-};
-
-static int pci_slot_ar[MAX_S514_CARDS];
-
-/******* Kernel Loadable Module Entry Points ********************************/
-
-/*============================================================================
- * Module 'insert' entry point.
- * o print announcement
- * o initialize static data
- * o calibrate SDLA shared memory access delay.
- *
- * Return:	0	Ok
- *		< 0	error.
- * Context:	process
- */
-
-static int __init sdladrv_init(void)
-{
-	int i=0;
-
-	printk(KERN_INFO "%s v%u.%u %s\n",
-		fullname, MOD_VERSION, MOD_RELEASE, copyright);
-	exec_idle = calibrate_delay(EXEC_DELAY);
-#ifdef WANDEBUG	
-	printk(KERN_DEBUG "%s: exec_idle = %d\n", modname, exec_idle);
-#endif	
-
-	/* Initialize the PCI Card array, which
-         * will store flags, used to mark 
-         * card initialization state */
-	for (i=0; i<MAX_S514_CARDS; i++)
-		pci_slot_ar[i] = 0xFF;
-
-	return 0;
-}
-
-/*============================================================================
- * Module 'remove' entry point.
- * o release all remaining system resources
- */
-static void __exit sdladrv_cleanup(void)
-{
-}
-
-module_init(sdladrv_init);
-module_exit(sdladrv_cleanup);
-
-/******* Kernel APIs ********************************************************/
-
-/*============================================================================
- * Set up adapter.
- * o detect adapter type
- * o verify hardware configuration options
- * o check for hardware conflicts
- * o set up adapter shared memory
- * o test adapter memory
- * o load firmware
- * Return:	0	ok.
- *		< 0	error
- */
-
-EXPORT_SYMBOL(sdla_setup);
-
-int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
-{
-	unsigned* irq_opt	= NULL;	/* IRQ options */
-	unsigned* dpmbase_opt	= NULL;	/* DPM window base options */
-	unsigned* pclk_opt	= NULL;	/* CPU clock rate options */
-	int err=0;
-
-	if (sdla_detect(hw)) {
-                if(hw->type != SDLA_S514)
-                        printk(KERN_INFO "%s: no SDLA card found at port 0x%X\n",
-                        modname, hw->port);
-		return -EINVAL;
-	}
-
-	if(hw->type != SDLA_S514) {
-                printk(KERN_INFO "%s: found S%04u card at port 0x%X.\n",
-                modname, hw->type, hw->port);
-
-                hw->dpmsize = SDLA_WINDOWSIZE;
-                switch (hw->type) {
-                case SDLA_S502A:
-                        hw->io_range    = S502A_IORANGE;
-                        irq_opt         = s502a_irq_options;
-                        dpmbase_opt     = s502a_dpmbase_options;
-                        pclk_opt        = s502a_pclk_options;
-                        break;
-
-                case SDLA_S502E:
-                        hw->io_range    = S502E_IORANGE;
-                        irq_opt         = s502e_irq_options;
-                        dpmbase_opt     = s508_dpmbase_options;
-                        pclk_opt        = s502e_pclk_options;
-                        break;
-
-                case SDLA_S503:
-                        hw->io_range    = S503_IORANGE;
-                        irq_opt         = s503_irq_options;
-                        dpmbase_opt     = s508_dpmbase_options;
-                        pclk_opt        = s503_pclk_options;
-                        break;
-
-                case SDLA_S507:
-                        hw->io_range    = S507_IORANGE;
-                        irq_opt         = s508_irq_options;
-                        dpmbase_opt     = s507_dpmbase_options;
-                        pclk_opt        = s507_pclk_options;
-                        break;
-
-                case SDLA_S508:
-                        hw->io_range    = S508_IORANGE;
-                        irq_opt         = s508_irq_options;
-                        dpmbase_opt     = s508_dpmbase_options;
-                        pclk_opt        = s508_pclk_options;
-                        break;
-                }
-
-                /* Verify IRQ configuration options */
-                if (!get_option_index(irq_opt, hw->irq)) {
-                        printk(KERN_INFO "%s: IRQ %d is invalid!\n",
-                        	modname, hw->irq);
-                      return -EINVAL;
-                } 
-
-                /* Verify CPU clock rate configuration options */
-                if (hw->pclk == 0)
-                        hw->pclk = pclk_opt[1];  /* use default */
-        
-                else if (!get_option_index(pclk_opt, hw->pclk)) {
-                        printk(KERN_INFO "%s: CPU clock %u is invalid!\n",
-				modname, hw->pclk);
-                        return -EINVAL;
-                } 
-                printk(KERN_INFO "%s: assuming CPU clock rate of %u kHz.\n",
-			modname, hw->pclk);
-
-                /* Setup adapter dual-port memory window and test memory */
-                if (hw->dpmbase == 0) {
-                        err = sdla_autodpm(hw);
-                        if (err) {
-                                printk(KERN_INFO
-				"%s: can't find available memory region!\n",
-					modname);
-                                return err;
-                        }
-                }
-                else if (!get_option_index(dpmbase_opt,
-			virt_to_phys(hw->dpmbase))) {
-                        printk(KERN_INFO
-				"%s: memory address 0x%lX is invalid!\n",
-				modname, virt_to_phys(hw->dpmbase));
-                        return -EINVAL;
-                }               
-                else if (sdla_setdpm(hw)) {
-                        printk(KERN_INFO
-			"%s: 8K memory region at 0x%lX is not available!\n",
-				modname, virt_to_phys(hw->dpmbase));
-                        return -EINVAL;
-                } 
-                printk(KERN_INFO
-			"%s: dual-port memory window is set at 0x%lX.\n",
-				modname, virt_to_phys(hw->dpmbase));
-
-
-		/* If we find memory in 0xE**** Memory region, 
-                 * warn the user to disable the SHADOW RAM.  
-                 * Since memory corruption can occur if SHADOW is
-                 * enabled. This can causes random crashes ! */
-		if (virt_to_phys(hw->dpmbase) >= 0xE0000){
-			printk(KERN_WARNING "\n%s: !!!!!!!!  WARNING !!!!!!!!\n",modname);
-			printk(KERN_WARNING "%s: WANPIPE is using 0x%lX memory region !!!\n",
-						modname, virt_to_phys(hw->dpmbase));
-			printk(KERN_WARNING "         Please disable the SHADOW RAM, otherwise\n");
-			printk(KERN_WARNING "         your system might crash randomly from time to time !\n");
-			printk(KERN_WARNING "%s: !!!!!!!!  WARNING !!!!!!!!\n\n",modname);
-		}
-        }
-
-	else {
-		hw->memory = test_memregion((void*)hw->dpmbase, 
-			MAX_SIZEOF_S514_MEMORY);
-		if(hw->memory < (256 * 1024)) {
-			printk(KERN_INFO
-				"%s: error in testing S514 memory (0x%lX)\n",
-				modname, hw->memory);
-			sdla_down(hw);
-			return -EINVAL;
-		}
-	}
-    
-	printk(KERN_INFO "%s: found %luK bytes of on-board memory\n",
-		modname, hw->memory / 1024);
-
-	/* Load firmware. If loader fails then shut down adapter */
-	err = sdla_load(hw, sfm, len);
-	if (err) sdla_down(hw);		/* shutdown adapter */
-
-	return err;
-} 
-
-/*============================================================================
- * Shut down SDLA: disable shared memory access and interrupts, stop CPU, etc.
- */
-
-EXPORT_SYMBOL(sdla_down);
-
-int sdla_down (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int i;
-        unsigned char CPU_no;
-        u32 int_config, int_status;
-
-        if(!port && (hw->type != SDLA_S514))
-                return -EFAULT;
-
-	switch (hw->type) {
-	case SDLA_S502A:
-		_OUTB(port, 0x08);		/* halt CPU */
-		_OUTB(port, 0x08);
-		_OUTB(port, 0x08);
-		hw->regs[0] = 0x08;
-		_OUTB(port + 1, 0xFF);		/* close memory window */
-		hw->regs[1] = 0xFF;
-		break;
-
-	case SDLA_S502E:
-		_OUTB(port + 3, 0);		/* stop CPU */
-		_OUTB(port, 0);			/* reset board */
-		for (i = 0; i < S502E_IORANGE; ++i)
-			hw->regs[i] = 0
-		;
-		break;
-
-	case SDLA_S503:
-	case SDLA_S507:
-	case SDLA_S508:
-		_OUTB(port, 0);			/* reset board logic */
-		hw->regs[0] = 0;
-		break;
-
-	case SDLA_S514:
-		/* halt the adapter */
-                *(char *)hw->vector = S514_CPU_HALT;
-        	CPU_no = hw->S514_cpu_no[0];
-
-		/* disable the PCI IRQ and disable memory access */
-                pci_read_config_dword(hw->pci_dev, PCI_INT_CONFIG, &int_config);
-	        int_config &= (CPU_no == S514_CPU_A) ? ~PCI_DISABLE_IRQ_CPU_A :	~PCI_DISABLE_IRQ_CPU_B;
-                pci_write_config_dword(hw->pci_dev, PCI_INT_CONFIG, int_config);
-		read_S514_int_stat(hw, &int_status);
-		S514_intack(hw, int_status);
-		if(CPU_no == S514_CPU_A)
-                        pci_write_config_dword(hw->pci_dev, PCI_MAP0_DWORD,
-				PCI_CPU_A_MEM_DISABLE);
-		else
-                        pci_write_config_dword(hw->pci_dev, PCI_MAP1_DWORD,
-				PCI_CPU_B_MEM_DISABLE);
-
-		/* free up the allocated virtual memory */
- 		iounmap((void *)hw->dpmbase);
-        	iounmap((void *)hw->vector);
- 		break;
-
-
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/*============================================================================
- * Map shared memory window into SDLA address space.
- */
-
-EXPORT_SYMBOL(sdla_mapmem);
-
-int sdla_mapmem (sdlahw_t* hw, unsigned long addr)
-{
-	unsigned port = hw->port;
-	register int tmp;
-
-	switch (hw->type) {
-	case SDLA_S502A:
-	case SDLA_S502E:
-		if (addr < S502_MAXMEM)	{ /* verify parameter */
-			tmp = addr >> 13;	/* convert to register mask */
-			_OUTB(port + 2, tmp);
-			hw->regs[2] = tmp;
-		}
-		else return -EINVAL;
-		break;
-
-	case SDLA_S503:
-		if (addr < S503_MAXMEM)	{ /* verify parameter */
-			tmp = (hw->regs[0] & 0x8F) | ((addr >> 9) & 0x70);
-			_OUTB(port, tmp);
-			hw->regs[0] = tmp;
-		}
-		else return -EINVAL;
-		break;
-
-	case SDLA_S507:
-		if (addr < S507_MAXMEM) {
-			if (!(_INB(port) & 0x02))
-				return -EIO;
-			tmp = addr >> 13;	/* convert to register mask */
-			_OUTB(port + 2, tmp);
-			hw->regs[2] = tmp;
-		}
-		else return -EINVAL;
-		break;
-
-	case SDLA_S508:
-		if (addr < S508_MAXMEM) {
-			tmp = addr >> 13;	/* convert to register mask */
-			_OUTB(port + 2, tmp);
-			hw->regs[2] = tmp;
-		}
-		else return -EINVAL;
-		break;
-
-	case SDLA_S514:
-		return 0;
-
- 	default:
-		return -EINVAL;
-	}
-	hw->vector = addr & 0xFFFFE000L;
-	return 0;
-}
-
-/*============================================================================
- * Enable interrupt generation.
- */
-
-static int sdla_inten (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int tmp, i;
-
-	switch (hw->type) {
-	case SDLA_S502E:
-		/* Note thar interrupt control operations on S502E are allowed
-		 * only if CPU is enabled (bit 0 of status register is set).
-		 */
-		if (_INB(port) & 0x01) {
-			_OUTB(port, 0x02);	/* bit1 = 1, bit2 = 0 */
-			_OUTB(port, 0x06);	/* bit1 = 1, bit2 = 1 */
-			hw->regs[0] = 0x06;
-		}
-		else return -EIO;
-		break;
-
-	case SDLA_S503:
-		tmp = hw->regs[0] | 0x04;
-		_OUTB(port, tmp);
-		hw->regs[0] = tmp;		/* update mirror */
-		for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-		if (!(_INB(port) & 0x02))		/* verify */
-			return -EIO;
-		break;
-
-	case SDLA_S508:
-		tmp = hw->regs[0] | 0x10;
-		_OUTB(port, tmp);
-		hw->regs[0] = tmp;		/* update mirror */
-		for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-		if (!(_INB(port + 1) & 0x10))		/* verify */
-			return -EIO;
-		break;
-
-	case SDLA_S502A:
-	case SDLA_S507:
-		break;
-
-        case SDLA_S514:
-                break;
-
-	default:
-		return -EINVAL;
-
-	}
-	return 0;
-}
-
-/*============================================================================
- * Disable interrupt generation.
- */
-
-#if 0
-int sdla_intde (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int tmp, i;
-
-	switch (hw->type) {
-	case SDLA_S502E:
-		/* Notes:
-		 *  1) interrupt control operations are allowed only if CPU is
-		 *     enabled (bit 0 of status register is set).
-		 *  2) disabling interrupts using bit 1 of control register
-		 *     causes IRQ line go high, therefore we are going to use
-		 *     0x04 instead: lower it to inhibit interrupts to PC.
-		 */
-		if (_INB(port) & 0x01) {
-			_OUTB(port, hw->regs[0] & ~0x04);
-			hw->regs[0] &= ~0x04;
-		}
-		else return -EIO;
-		break;
-
-	case SDLA_S503:
-		tmp = hw->regs[0] & ~0x04;
-		_OUTB(port, tmp);
-		hw->regs[0] = tmp;			/* update mirror */
-		for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-		if (_INB(port) & 0x02)			/* verify */
-			return -EIO;
-		break;
-
-	case SDLA_S508:
-		tmp = hw->regs[0] & ~0x10;
-		_OUTB(port, tmp);
-		hw->regs[0] = tmp;			/* update mirror */
-		for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-		if (_INB(port) & 0x10)			/* verify */
-			return -EIO;
-		break;
-
-	case SDLA_S502A:
-	case SDLA_S507:
-		break;
-
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-#endif  /*  0  */
-
-/*============================================================================
- * Acknowledge SDLA hardware interrupt.
- */
-
-static int sdla_intack (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int tmp;
-
-	switch (hw->type) {
-	case SDLA_S502E:
-		/* To acknoledge hardware interrupt we have to toggle bit 3 of
-		 * control register: \_/
-		 * Note that interrupt control operations on S502E are allowed
-		 * only if CPU is enabled (bit 1 of status register is set).
-		 */
-		if (_INB(port) & 0x01) {
-			tmp = hw->regs[0] & ~0x04;
-			_OUTB(port, tmp);
-			tmp |= 0x04;
-			_OUTB(port, tmp);
-			hw->regs[0] = tmp;
-		}
-		else return -EIO;
-		break;
-
-	case SDLA_S503:
-		if (_INB(port) & 0x04) {
-			tmp = hw->regs[0] & ~0x08;
-			_OUTB(port, tmp);
-			tmp |= 0x08;
-			_OUTB(port, tmp);
-			hw->regs[0] = tmp;
-		}
-		break;
-
-	case SDLA_S502A:
-	case SDLA_S507:
-	case SDLA_S508:
-	break;
-
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-
-/*============================================================================
- * Acknowledge S514 hardware interrupt.
- */
-
-EXPORT_SYMBOL(S514_intack);
-
-void S514_intack (sdlahw_t* hw, u32 int_status)
-{
-        pci_write_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
-}
-
-
-/*============================================================================
- * Read the S514 hardware interrupt status.
- */
-
-EXPORT_SYMBOL(read_S514_int_stat);
-
-void read_S514_int_stat (sdlahw_t* hw, u32* int_status)
-{
-	pci_read_config_dword(hw->pci_dev, PCI_INT_STATUS, int_status);
-}
-
-
-/*============================================================================
- * Generate an interrupt to adapter's CPU.
- */
-
-#if 0
-int sdla_intr (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-
-	switch (hw->type) {
-	case SDLA_S502A:
-		if (!(_INB(port) & 0x40)) {
-			_OUTB(port, 0x10);		/* issue NMI to CPU */
-			hw->regs[0] = 0x10;
-		}
-		else return -EIO;
-		break;
-
-	case SDLA_S507:
-		if ((_INB(port) & 0x06) == 0x06) {
-			_OUTB(port + 3, 0);
-		}
-		else return -EIO;
-		break;
-
-	case SDLA_S508:
-		if (_INB(port + 1) & 0x02) {
-			_OUTB(port, 0x08);
-		}
-		else return -EIO;
-		break;
-
-	case SDLA_S502E:
-	case SDLA_S503:
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-#endif  /*  0  */
-
-/*============================================================================
- * Execute Adapter Command.
- * o Set exec flag.
- * o Busy-wait until flag is reset.
- * o Return number of loops made, or 0 if command timed out.
- */
-
-EXPORT_SYMBOL(sdla_exec);
-
-int sdla_exec (void* opflag)
-{
-	volatile unsigned char* flag = opflag;
-	unsigned long tstop;
-	int nloops;
-
-	if(readb(flag) != 0x00) {
-		printk(KERN_INFO
-			"WANPIPE: opp flag set on entry to sdla_exec\n");
-		return 0;
-	}
-	
-	writeb(0x01, flag);
-
-	tstop = SYSTEM_TICK + EXEC_TIMEOUT;
-
-	for (nloops = 1; (readb(flag) == 0x01); ++ nloops) {
-		unsigned delay = exec_idle;
-		while (-- delay);			/* delay */
-		if (SYSTEM_TICK > tstop) return 0;	/* time is up! */
-	}
-	return nloops;
-}
-
-/*============================================================================
- * Read absolute adapter memory.
- * Transfer data from adapter's memory to data buffer.
- *
- * Note:
- * Care should be taken when crossing dual-port memory window boundary.
- * This function is not atomic, so caller must disable interrupt if
- * interrupt routines are accessing adapter shared memory.
- */
-
-EXPORT_SYMBOL(sdla_peek);
-
-int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
-{
-
-	if (addr + len > hw->memory)	/* verify arguments */
-		return -EINVAL;
-
-        if(hw->type == SDLA_S514) {	/* copy data for the S514 adapter */
-                peek_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
-                return 0;
-	}
-
-        else {				/* copy data for the S508 adapter */
-	        unsigned long oldvec = hw->vector;
-        	unsigned winsize = hw->dpmsize;
-	        unsigned curpos, curlen;   /* current offset and block size */
-        	unsigned long curvec;      /* current DPM window vector */
-	        int err = 0;
-
-                while (len && !err) {
-                        curpos = addr % winsize;  /* current window offset */
-                        curvec = addr - curpos;   /* current window vector */
-                        curlen = (len > (winsize - curpos)) ?
-				(winsize - curpos) : len;
-                        /* Relocate window and copy block of data */
-                        err = sdla_mapmem(hw, curvec);
-                        peek_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
-				curlen);
-                        addr       += curlen;
-                        buf         = (char*)buf + curlen;
-                        len        -= curlen;
-                }
-
-                /* Restore DPM window position */
-                sdla_mapmem(hw, oldvec);
-                return err;
-        }
-}
-
-
-/*============================================================================
- * Read data from adapter's memory to a data buffer in 4-byte chunks.
- * Note that we ensure that the SDLA memory address is on a 4-byte boundary
- * before we begin moving the data in 4-byte chunks.
-*/
-
-static void peek_by_4 (unsigned long src, void* buf, unsigned len)
-{
-
-        /* byte copy data until we get to a 4-byte boundary */
-        while (len && (src & 0x03)) {
-                *(char *)buf ++ = readb(src ++);
-                len --;
-        }
-
-        /* copy data in 4-byte chunks */
-        while (len >= 4) {
-                *(unsigned long *)buf = readl(src);
-                buf += 4;
-                src += 4;
-                len -= 4;
-        }
-
-        /* byte copy any remaining data */
-        while (len) {
-                *(char *)buf ++ = readb(src ++);
-                len --;
-        }
-}
-
-
-/*============================================================================
- * Write Absolute Adapter Memory.
- * Transfer data from data buffer to adapter's memory.
- *
- * Note:
- * Care should be taken when crossing dual-port memory window boundary.
- * This function is not atomic, so caller must disable interrupt if
- * interrupt routines are accessing adapter shared memory.
- */
-
-EXPORT_SYMBOL(sdla_poke);
- 
-int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
-{
-
-	if (addr + len > hw->memory)	/* verify arguments */
-		return -EINVAL;
-   
-        if(hw->type == SDLA_S514) {	/* copy data for the S514 adapter */
-                poke_by_4 ((unsigned long)hw->dpmbase + addr, buf, len);
-                return 0;
-	}
-	
-	else {				/* copy data for the S508 adapter */
-    		unsigned long oldvec = hw->vector;
-	        unsigned winsize = hw->dpmsize;
-        	unsigned curpos, curlen;     /* current offset and block size */
-        	unsigned long curvec;        /* current DPM window vector */
-        	int err = 0;
-
-		while (len && !err) {
-                        curpos = addr % winsize;    /* current window offset */
-                        curvec = addr - curpos;     /* current window vector */
-                        curlen = (len > (winsize - curpos)) ?
-				(winsize - curpos) : len;
-                        /* Relocate window and copy block of data */
-                        sdla_mapmem(hw, curvec);
-                        poke_by_4 ((unsigned long)hw->dpmbase + curpos, buf,
-				curlen);
-	                addr       += curlen;
-                        buf         = (char*)buf + curlen;
-                        len        -= curlen;
-                }
-
-                /* Restore DPM window position */
-                sdla_mapmem(hw, oldvec);
-                return err;
-        }
-}
-
-
-/*============================================================================
- * Write from a data buffer to adapter's memory in 4-byte chunks.
- * Note that we ensure that the SDLA memory address is on a 4-byte boundary
- * before we begin moving the data in 4-byte chunks.
-*/
-
-static void poke_by_4 (unsigned long dest, void* buf, unsigned len)
-{
-
-        /* byte copy data until we get to a 4-byte boundary */
-        while (len && (dest & 0x03)) {
-                writeb (*(char *)buf ++, dest ++);
-                len --;
-        }
-
-        /* copy data in 4-byte chunks */
-        while (len >= 4) {
-                writel (*(unsigned long *)buf, dest);
-                dest += 4;
-                buf += 4;
-                len -= 4;
-        }
-
-        /* byte copy any remaining data */
-        while (len) {
-                writeb (*(char *)buf ++ , dest ++);
-                len --;
-        }
-}
-
-
-#ifdef	DONT_COMPIPLE_THIS
-#endif	/* DONT_COMPIPLE_THIS */
-
-/****** Hardware-Specific Functions *****************************************/
-
-/*============================================================================
- * Detect adapter type.
- * o if adapter type is specified then call detection routine for that adapter
- *   type.  Otherwise call detection routines for every adapter types until
- *   adapter is detected.
- *
- * Notes:
- * 1) Detection tests are destructive! Adapter will be left in shutdown state
- *    after the test.
- */
-static int sdla_detect (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int err = 0;
-
-	if (!port && (hw->type != SDLA_S514))
-		return -EFAULT;
-
-    	switch (hw->type) {
-	case SDLA_S502A:
-		if (!detect_s502a(port)) err = -ENODEV;
-		break;
-
-	case SDLA_S502E:
-		if (!detect_s502e(port)) err = -ENODEV;
-		break;
-
-	case SDLA_S503:
-		if (!detect_s503(port)) err = -ENODEV;
-		break;
-
-	case SDLA_S507:
-		if (!detect_s507(port)) err = -ENODEV;
-		break;
-
-	case SDLA_S508:
-		if (!detect_s508(port)) err = -ENODEV;
-		break;
-
-	case SDLA_S514:
-                if (!detect_s514(hw)) err = -ENODEV;
-		break;
-
-	default:
-		if (detect_s502a(port))
-			hw->type = SDLA_S502A;
-		else if (detect_s502e(port))
-			hw->type = SDLA_S502E;
-		else if (detect_s503(port))
-			hw->type = SDLA_S503;
-		else if (detect_s507(port))
-			hw->type = SDLA_S507;
-		else if (detect_s508(port))
-			hw->type = SDLA_S508;
-		else err = -ENODEV;
-	}
-	return err;
-}
-
-/*============================================================================
- * Autoselect memory region. 
- * o try all available DMP address options from the top down until success.
- */
-static int sdla_autodpm (sdlahw_t* hw)
-{
-	int i, err = -EINVAL;
-	unsigned* opt;
-
-	switch (hw->type) {
-	case SDLA_S502A:
-		opt = s502a_dpmbase_options;
-		break;
-
-	case SDLA_S502E:
-	case SDLA_S503:
-	case SDLA_S508:
-		opt = s508_dpmbase_options;
-		break;
-
-	case SDLA_S507:
-		opt = s507_dpmbase_options;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Start testing from 8th position, address
-         * 0xC8000 from the 508 address table. 
-         * We don't want to test A**** addresses, since
-         * they are usually used for Video */
-	for (i = 8; i <= opt[0] && err; i++) {
-		hw->dpmbase = phys_to_virt(opt[i]);
-		err = sdla_setdpm(hw);
-	}
-	return err;
-}
-
-/*============================================================================
- * Set up adapter dual-port memory window. 
- * o shut down adapter
- * o make sure that no physical memory exists in this region, i.e entire
- *   region reads 0xFF and is not writable when adapter is shut down.
- * o initialize adapter hardware
- * o make sure that region is usable with SDLA card, i.e. we can write to it
- *   when adapter is configured.
- */
-static int sdla_setdpm (sdlahw_t* hw)
-{
-	int err;
-
-	/* Shut down card and verify memory region */
-	sdla_down(hw);
-	if (check_memregion(hw->dpmbase, hw->dpmsize))
-		return -EINVAL;
-
-	/* Initialize adapter and test on-board memory segment by segment.
-	 * If memory size appears to be less than shared memory window size,
-	 * assume that memory region is unusable.
-	 */
-	err = sdla_init(hw);
-	if (err) return err;
-
-	if (sdla_memtest(hw) < hw->dpmsize) {	/* less than window size */
-		sdla_down(hw);
-		return -EIO;
-	}
-	sdla_mapmem(hw, 0L);	/* set window vector at bottom */
-	return 0;
-}
-
-/*============================================================================
- * Load adapter from the memory image of the SDLA firmware module. 
- * o verify firmware integrity and compatibility
- * o start adapter up
- */
-static int sdla_load (sdlahw_t* hw, sfm_t* sfm, unsigned len)
-{
-
-	int i;
-
-	/* Verify firmware signature */
-	if (strcmp(sfm->signature, SFM_SIGNATURE)) {
-		printk(KERN_INFO "%s: not SDLA firmware!\n",
-			modname);
-		return -EINVAL;
-	}
-
-	/* Verify firmware module format version */
-	if (sfm->version != SFM_VERSION) {
-		printk(KERN_INFO
-			"%s: firmware format %u rejected! Expecting %u.\n",
-			modname, sfm->version, SFM_VERSION);
-		return -EINVAL;
-	}
-
-	/* Verify firmware module length and checksum */
-	if ((len - offsetof(sfm_t, image) != sfm->info.codesize) ||
-		(checksum((void*)&sfm->info,
-		sizeof(sfm_info_t) + sfm->info.codesize) != sfm->checksum)) {
-		printk(KERN_INFO "%s: firmware corrupted!\n", modname);
-		return -EINVAL;
-	}
-
-	/* Announce */
-	printk(KERN_INFO "%s: loading %s (ID=%u)...\n", modname,
-		(sfm->descr[0] != '\0') ? sfm->descr : "unknown firmware",
-		sfm->info.codeid);
-
-	if(hw->type == SDLA_S514)
-		printk(KERN_INFO "%s: loading S514 adapter, CPU %c\n",
-			modname, hw->S514_cpu_no[0]);
-
-	/* Scan through the list of compatible adapters and make sure our
-	 * adapter type is listed.
-	 */
-	for (i = 0;
-	     (i < SFM_MAX_SDLA) && (sfm->info.adapter[i] != hw->type);
-	     ++i);
-	
-	if (i == SFM_MAX_SDLA) {
-		printk(KERN_INFO "%s: firmware is not compatible with S%u!\n",
-			modname, hw->type);
-		return -EINVAL;
-	}
-
-
-	/* Make sure there is enough on-board memory */
-	if (hw->memory < sfm->info.memsize) {
-		printk(KERN_INFO
-			"%s: firmware needs %lu bytes of on-board memory!\n",
-			modname, sfm->info.memsize);
-		return -EINVAL;
-	}
-
-	/* Move code onto adapter */
-	if (sdla_poke(hw, sfm->info.codeoffs, sfm->image, sfm->info.codesize)) {
-		printk(KERN_INFO "%s: failed to load code segment!\n",
-			modname);
-		return -EIO;
-	}
-
-	/* Prepare boot-time configuration data and kick-off CPU */
-	sdla_bootcfg(hw, &sfm->info);
-	if (sdla_start(hw, sfm->info.startoffs)) {
-		printk(KERN_INFO "%s: Damn... Adapter won't start!\n",
-			modname);
-		return -EIO;
-	}
-
-	/* position DPM window over the mailbox and enable interrupts */
-        if (sdla_mapmem(hw, sfm->info.winoffs) || sdla_inten(hw)) {
-		printk(KERN_INFO "%s: adapter hardware failure!\n",
-			modname);
-		return -EIO;
-	}
-	hw->fwid = sfm->info.codeid;		/* set firmware ID */
-	return 0;
-}
-
-/*============================================================================
- * Initialize SDLA hardware: setup memory window, IRQ, etc.
- */
-static int sdla_init (sdlahw_t* hw)
-{
-	int i;
-
-	for (i = 0; i < SDLA_MAXIORANGE; ++i)
-		hw->regs[i] = 0;
-
-	switch (hw->type) {
-	case SDLA_S502A: return init_s502a(hw);
-	case SDLA_S502E: return init_s502e(hw);
-	case SDLA_S503:  return init_s503(hw);
-	case SDLA_S507:  return init_s507(hw);
-	case SDLA_S508:  return init_s508(hw);
-	}
-	return -EINVAL;
-}
-
-/*============================================================================
- * Test adapter on-board memory.
- * o slide DPM window from the bottom up and test adapter memory segment by
- *   segment.
- * Return adapter memory size.
- */
-static unsigned long sdla_memtest (sdlahw_t* hw)
-{
-	unsigned long memsize;
-	unsigned winsize;
-
-	for (memsize = 0, winsize = hw->dpmsize;
-	     !sdla_mapmem(hw, memsize) &&
-		(test_memregion(hw->dpmbase, winsize) == winsize)
-	     ;
-	     memsize += winsize)
-	;
-	hw->memory = memsize;
-	return memsize;
-}
-
-/*============================================================================
- * Prepare boot-time firmware configuration data.
- * o position DPM window
- * o initialize configuration data area
- */
-static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
-{
-	unsigned char* data;
-
-	if (!sfminfo->datasize) return 0;	/* nothing to do */
-
-	if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
-		return -EIO;
-
-	if(hw->type == SDLA_S514)
-                data = (void*)(hw->dpmbase + sfminfo->dataoffs);
-        else
-                data = (void*)((u8 *)hw->dpmbase +
-                        (sfminfo->dataoffs - hw->vector));
-
-	memset_io (data, 0, sfminfo->datasize);
-
-	writeb (make_config_byte(hw), &data[0x00]);
-
-	switch (sfminfo->codeid) {
-	case SFID_X25_502:
-	case SFID_X25_508:
-                writeb (3, &data[0x01]);        /* T1 timer */
-                writeb (10, &data[0x03]);       /* N2 */
-                writeb (7, &data[0x06]);        /* HDLC window size */
-                writeb (1, &data[0x0B]);        /* DTE */
-                writeb (2, &data[0x0C]);        /* X.25 packet window size */
-                writew (128, &data[0x0D]);	/* default X.25 data size */
-                writew (128, &data[0x0F]);	/* maximum X.25 data size */
-		break;
-	}
-	return 0;
-}
-
-/*============================================================================
- * Prepare configuration byte identifying adapter type and CPU clock rate.
- */
-static unsigned char make_config_byte (sdlahw_t* hw)
-{
-	unsigned char byte = 0;
-
-	switch (hw->pclk) {
-		case 5000:  byte = 0x01; break;
-		case 7200:  byte = 0x02; break;
-		case 8000:  byte = 0x03; break;
-		case 10000: byte = 0x04; break;
-		case 16000: byte = 0x05; break;
-	}
-
-	switch (hw->type) {
-		case SDLA_S502E: byte |= 0x80; break;
-		case SDLA_S503:  byte |= 0x40; break;
-	}
-	return byte;
-}
-
-/*============================================================================
- * Start adapter's CPU.
- * o calculate a pointer to adapter's cold boot entry point
- * o position DPM window
- * o place boot instruction (jp addr) at cold boot entry point
- * o start CPU
- */
-static int sdla_start (sdlahw_t* hw, unsigned addr)
-{
-	unsigned port = hw->port;
-	unsigned char *bootp;
-	int err, tmp, i;
-
-	if (!port && (hw->type != SDLA_S514)) return -EFAULT;
-
- 	switch (hw->type) {
-	case SDLA_S502A:
-		bootp = hw->dpmbase;
-		bootp += 0x66;
-		break;
-
-	case SDLA_S502E:
-	case SDLA_S503:
-	case SDLA_S507:
-	case SDLA_S508:
-	case SDLA_S514:
-		bootp = hw->dpmbase;
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	err = sdla_mapmem(hw, 0);
-	if (err) return err;
-
-      	writeb (0xC3, bootp);   /* Z80: 'jp' opcode */
-	bootp ++;
-	writew (addr, bootp);
-
-	switch (hw->type) {
-	case SDLA_S502A:
-		_OUTB(port, 0x10);		/* issue NMI to CPU */
-		hw->regs[0] = 0x10;
-		break;
-
-	case SDLA_S502E:
-		_OUTB(port + 3, 0x01);		/* start CPU */
-		hw->regs[3] = 0x01;
-		for (i = 0; i < SDLA_IODELAY; ++i);
-		if (_INB(port) & 0x01) {	/* verify */
-			/*
-			 * Enabling CPU changes functionality of the
-			 * control register, so we have to reset its
-			 * mirror.
-			 */
-			_OUTB(port, 0);		/* disable interrupts */
-			hw->regs[0] = 0;
-		}
-		else return -EIO;
-		break;
-
-	case SDLA_S503:
-		tmp = hw->regs[0] | 0x09;	/* set bits 0 and 3 */
-		_OUTB(port, tmp);
-		hw->regs[0] = tmp;		/* update mirror */
-		for (i = 0; i < SDLA_IODELAY; ++i);
-		if (!(_INB(port) & 0x01))	/* verify */
-			return -EIO;
-		break;
-
-	case SDLA_S507:
-		tmp = hw->regs[0] | 0x02;
-		_OUTB(port, tmp);
-		hw->regs[0] = tmp;		/* update mirror */
-		for (i = 0; i < SDLA_IODELAY; ++i);
-		if (!(_INB(port) & 0x04))	/* verify */
-			return -EIO;
-		break;
-
-	case SDLA_S508:
-		tmp = hw->regs[0] | 0x02;
-		_OUTB(port, tmp);
-		hw->regs[0] = tmp;	/* update mirror */
-		for (i = 0; i < SDLA_IODELAY; ++i);
-		if (!(_INB(port + 1) & 0x02))	/* verify */
-			return -EIO;
-		break;
-
-	case SDLA_S514:
-		writeb (S514_CPU_START, hw->vector);
-		break;
-
-	default:
-		return -EINVAL;
-	}
-	return 0;
-}
-
-/*============================================================================
- * Initialize S502A adapter.
- */
-static int init_s502a (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int tmp, i;
-
-	if (!detect_s502a(port))
-		return -ENODEV;
-
-	hw->regs[0] = 0x08;
-	hw->regs[1] = 0xFF;
-
-	/* Verify configuration options */
-	i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
-	if (i == 0)
-		return -EINVAL;
-
-	tmp = s502a_hmcr[i - 1];
-	switch (hw->dpmsize) {
-	case 0x2000:
-		tmp |= 0x01;
-		break;
-
-	case 0x10000L:
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Setup dual-port memory window (this also enables memory access) */
-	_OUTB(port + 1, tmp);
-	hw->regs[1] = tmp;
-	hw->regs[0] = 0x08;
-	return 0;
-}
-
-/*============================================================================
- * Initialize S502E adapter.
- */
-static int init_s502e (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int tmp, i;
-
-	if (!detect_s502e(port))
-		return -ENODEV;
-
-	/* Verify configuration options */
-	i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
-	if (i == 0)
-		return -EINVAL;
-
-	tmp = s502e_hmcr[i - 1];
-	switch (hw->dpmsize) {
-	case 0x2000:
-		tmp |= 0x01;
-		break;
-
-	case 0x10000L:
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Setup dual-port memory window */
-	_OUTB(port + 1, tmp);
-	hw->regs[1] = tmp;
-
-	/* Enable memory access */
-	_OUTB(port, 0x02);
-	hw->regs[0] = 0x02;
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	return (_INB(port) & 0x02) ? 0 : -EIO;
-}
-
-/*============================================================================
- * Initialize S503 adapter.
- * ---------------------------------------------------------------------------
- */
-static int init_s503 (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int tmp, i;
-
-	if (!detect_s503(port))
-		return -ENODEV;
-
-	/* Verify configuration options */
-	i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
-	if (i == 0)
-		return -EINVAL;
-
-	tmp = s502e_hmcr[i - 1];
-	switch (hw->dpmsize) {
-	case 0x2000:
-		tmp |= 0x01;
-		break;
-
-	case 0x10000L:
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Setup dual-port memory window */
-	_OUTB(port + 1, tmp);
-	hw->regs[1] = tmp;
-
-	/* Enable memory access */
-	_OUTB(port, 0x02);
-	hw->regs[0] = 0x02;	/* update mirror */
-	return 0;
-}
-
-/*============================================================================
- * Initialize S507 adapter.
- */
-static int init_s507 (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int tmp, i;
-
-	if (!detect_s507(port))
-		return -ENODEV;
-
-	/* Verify configuration options */
-	i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
-	if (i == 0)
-		return -EINVAL;
-
-	tmp = s507_hmcr[i - 1];
-	switch (hw->dpmsize) {
-	case 0x2000:
-		tmp |= 0x01;
-		break;
-
-	case 0x10000L:
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	/* Enable adapter's logic */
-	_OUTB(port, 0x01);
-	hw->regs[0] = 0x01;
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if (!(_INB(port) & 0x20))
-		return -EIO;
-
-	/* Setup dual-port memory window */
-	_OUTB(port + 1, tmp);
-	hw->regs[1] = tmp;
-
-	/* Enable memory access */
-	tmp = hw->regs[0] | 0x04;
-	if (hw->irq) {
-		i = get_option_index(s508_irq_options, hw->irq);
-		if (i) tmp |= s507_irqmask[i - 1];
-	}
-	_OUTB(port, tmp);
-	hw->regs[0] = tmp;		/* update mirror */
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	return (_INB(port) & 0x08) ? 0 : -EIO;
-}
-
-/*============================================================================
- * Initialize S508 adapter.
- */
-static int init_s508 (sdlahw_t* hw)
-{
-	unsigned port = hw->port;
-	int tmp, i;
-
-	if (!detect_s508(port))
-		return -ENODEV;
-
-	/* Verify configuration options */
-	i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
-	if (i == 0)
-		return -EINVAL;
-
-	/* Setup memory configuration */
-	tmp = s508_hmcr[i - 1];
-	_OUTB(port + 1, tmp);
-	hw->regs[1] = tmp;
-
-	/* Enable memory access */
-	_OUTB(port, 0x04);
-	hw->regs[0] = 0x04;		/* update mirror */
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	return (_INB(port + 1) & 0x04) ? 0 : -EIO;
-}
-
-/*============================================================================
- * Detect S502A adapter.
- *	Following tests are used to detect S502A adapter:
- *	1. All registers other than status (BASE) should read 0xFF
- *	2. After writing 00001000b to control register, status register should
- *	   read 01000000b.
- *	3. After writing 0 to control register, status register should still
- *	   read  01000000b.
- *	4. After writing 00000100b to control register, status register should
- *	   read 01000100b.
- *	Return 1 if detected o.k. or 0 if failed.
- *	Note:	This test is destructive! Adapter will be left in shutdown
- *		state after the test.
- */
-static int detect_s502a (int port)
-{
-	int i, j;
-
-	if (!get_option_index(s502_port_options, port))
-		return 0;
-	
-	for (j = 1; j < SDLA_MAXIORANGE; ++j) {
-		if (_INB(port + j) != 0xFF)
-			return 0;
-		for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	}
-
-	_OUTB(port, 0x08);			/* halt CPU */
-	_OUTB(port, 0x08);
-	_OUTB(port, 0x08);
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if (_INB(port) != 0x40)
-		return 0;
-	_OUTB(port, 0x00);
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if (_INB(port) != 0x40)
-		return 0;
-	_OUTB(port, 0x04);
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if (_INB(port) != 0x44)
-		return 0;
-
-	/* Reset adapter */
-	_OUTB(port, 0x08);
-	_OUTB(port, 0x08);
-	_OUTB(port, 0x08);
-	_OUTB(port + 1, 0xFF);
-	return 1;
-}
-
-/*============================================================================
- * Detect S502E adapter.
- *	Following tests are used to verify adapter presence:
- *	1. All registers other than status (BASE) should read 0xFF.
- *	2. After writing 0 to CPU control register (BASE+3), status register
- *	   (BASE) should read 11111000b.
- *	3. After writing 00000100b to port BASE (set bit 2), status register
- *	   (BASE) should read 11111100b.
- *	Return 1 if detected o.k. or 0 if failed.
- *	Note:	This test is destructive! Adapter will be left in shutdown
- *		state after the test.
- */
-static int detect_s502e (int port)
-{
-	int i, j;
-
-	if (!get_option_index(s502_port_options, port))
-		return 0;
-	for (j = 1; j < SDLA_MAXIORANGE; ++j) {
-		if (_INB(port + j) != 0xFF)
-			return 0;
-		for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	}
-
-	_OUTB(port + 3, 0);			/* CPU control reg. */
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if (_INB(port) != 0xF8)			/* read status */
-		return 0;
-	_OUTB(port, 0x04);			/* set bit 2 */
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if (_INB(port) != 0xFC)			/* verify */
-		return 0;
-
-	/* Reset adapter */
-	_OUTB(port, 0);
-	return 1;
-}
-
-/*============================================================================
- * Detect s503 adapter.
- *	Following tests are used to verify adapter presence:
- *	1. All registers other than status (BASE) should read 0xFF.
- *	2. After writing 0 to control register (BASE), status register (BASE)
- *	   should read 11110000b.
- *	3. After writing 00000100b (set bit 2) to control register (BASE),
- *	   status register should read 11110010b.
- *	Return 1 if detected o.k. or 0 if failed.
- *	Note:	This test is destructive! Adapter will be left in shutdown
- *		state after the test.
- */
-static int detect_s503 (int port)
-{
-	int i, j;
-
-	if (!get_option_index(s503_port_options, port))
-		return 0;
-	for (j = 1; j < SDLA_MAXIORANGE; ++j) {
-		if (_INB(port + j) != 0xFF)
-			return 0;
-		for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	}
-
-	_OUTB(port, 0);				/* reset control reg.*/
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if (_INB(port) != 0xF0)			/* read status */
-		return 0;
-	_OUTB(port, 0x04);			/* set bit 2 */
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if (_INB(port) != 0xF2)			/* verify */
-		return 0;
-
-	/* Reset adapter */
-	_OUTB(port, 0);
-	return 1;
-}
-
-/*============================================================================
- * Detect s507 adapter.
- *	Following tests are used to detect s507 adapter:
- *	1. All ports should read the same value.
- *	2. After writing 0x00 to control register, status register should read
- *	   ?011000?b.
- *	3. After writing 0x01 to control register, status register should read
- *	   ?011001?b.
- *	Return 1 if detected o.k. or 0 if failed.
- *	Note:	This test is destructive! Adapter will be left in shutdown
- *		state after the test.
- */
-static int detect_s507 (int port)
-{
-	int tmp, i, j;
-
-	if (!get_option_index(s508_port_options, port))
-		return 0;
-	tmp = _INB(port);
-	for (j = 1; j < S507_IORANGE; ++j) {
-		if (_INB(port + j) != tmp)
-			return 0;
-		for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	}
-
-	_OUTB(port, 0x00);
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if ((_INB(port) & 0x7E) != 0x30)
-		return 0;
-	_OUTB(port, 0x01);
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if ((_INB(port) & 0x7E) != 0x32)
-		return 0;
-
-	/* Reset adapter */
-	_OUTB(port, 0x00);
-	return 1;
-}
-
-/*============================================================================
- * Detect s508 adapter.
- *	Following tests are used to detect s508 adapter:
- *	1. After writing 0x00 to control register, status register should read
- *	   ??000000b.
- *	2. After writing 0x10 to control register, status register should read
- *	   ??010000b
- *	Return 1 if detected o.k. or 0 if failed.
- *	Note:	This test is destructive! Adapter will be left in shutdown
- *		state after the test.
- */
-static int detect_s508 (int port)
-{
-	int i;
-
-	if (!get_option_index(s508_port_options, port))
-		return 0;
-	_OUTB(port, 0x00);
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if ((_INB(port + 1) & 0x3F) != 0x00)
-		return 0;
-	_OUTB(port, 0x10);
-	for (i = 0; i < SDLA_IODELAY; ++i);	/* delay */
-	if ((_INB(port + 1) & 0x3F) != 0x10)
-		return 0;
-
-	/* Reset adapter */
-	_OUTB(port, 0x00);
-	return 1;
-}
-
-/*============================================================================
- * Detect s514 PCI adapter.
- *      Return 1 if detected o.k. or 0 if failed.
- *      Note:   This test is destructive! Adapter will be left in shutdown
- *              state after the test.
- */
-static int detect_s514 (sdlahw_t* hw)
-{
-	unsigned char CPU_no, slot_no, auto_slot_cfg;
-	int number_S514_cards = 0;
-	u32 S514_mem_base_addr = 0;
-	u32 ut_u32;
-	struct pci_dev *pci_dev;
-
-
-#ifndef CONFIG_PCI
-        printk(KERN_INFO "%s: Linux not compiled for PCI usage!\n", modname);
-        return 0;
-#endif
-
-	/*
-	The 'setup()' procedure in 'sdlamain.c' passes the CPU number and the
-	slot number defined in 'router.conf' via the 'port' definition.
-	*/
-	CPU_no = hw->S514_cpu_no[0];
-	slot_no = hw->S514_slot_no;
-	auto_slot_cfg = hw->auto_pci_cfg;
-
-	if (auto_slot_cfg){
-		printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot=Auto\n",
-		modname, CPU_no);
-
-	}else{
-		printk(KERN_INFO "%s: srch... S514 card, CPU %c, Slot #%d\n",
-		modname, CPU_no, slot_no);
-	}
-	
-	/* check to see that CPU A or B has been selected in 'router.conf' */
-	switch(CPU_no) {
-		case S514_CPU_A:
-		case S514_CPU_B:
-			break;
-	
-		default:
-			printk(KERN_INFO "%s: S514 CPU definition invalid.\n", 
-				modname);
-			printk(KERN_INFO "Must be 'A' or 'B'\n");
-			return 0;
-	}
-
-	number_S514_cards = find_s514_adapter(hw, 0);
-	if(!number_S514_cards)
-		return 0;
-
-	/* we are using a single S514 adapter with a slot of 0 so re-read the */	
-	/* location of this adapter */
-	if((number_S514_cards == 1) && auto_slot_cfg) {	
-        	number_S514_cards = find_s514_adapter(hw, 1);
-		if(!number_S514_cards) {
-			printk(KERN_INFO "%s: Error finding PCI card\n",
-				modname);
-			return 0;
-		}
-	}
-
-	pci_dev = hw->pci_dev;
-	/* read the physical memory base address */
-	S514_mem_base_addr = (CPU_no == S514_CPU_A) ? 
-		(pci_dev->resource[1].start) :
-		(pci_dev->resource[2].start);
-	
-	printk(KERN_INFO "%s: S514 PCI memory at 0x%X\n",
-		modname, S514_mem_base_addr);
-	if(!S514_mem_base_addr) {
-		if(CPU_no == S514_CPU_B)
-			printk(KERN_INFO "%s: CPU #B not present on the card\n", 				modname);
-		else
-			printk(KERN_INFO "%s: No PCI memory allocated to card\n",				modname);
-		return 0;
-	}
-
-	/* enable the PCI memory */
-	pci_read_config_dword(pci_dev, 
-		(CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
-		&ut_u32);
-	pci_write_config_dword(pci_dev,
-		(CPU_no == S514_CPU_A) ? PCI_MAP0_DWORD : PCI_MAP1_DWORD,
-		(ut_u32 | PCI_MEMORY_ENABLE));
-
-	/* check the IRQ allocated and enable IRQ usage */
-	if(!(hw->irq = pci_dev->irq)) {
-		printk(KERN_INFO "%s: IRQ not allocated to S514 adapter\n",
-			modname);
-                return 0;
-	}
-
-	/* BUG FIX : Mar 6 2000
- 	 * On a initial loading of the card, we must check
-         * and clear PCI interrupt bits, due to a reset
-         * problem on some other boards.  i.e. An interrupt
-         * might be pending, even after system bootup, 
-         * in which case, when starting wanrouter the machine
-         * would crash. 
-	 */
-	if (init_pci_slot(hw))
-		return 0;
-
-        pci_read_config_dword(pci_dev, PCI_INT_CONFIG, &ut_u32);
-        ut_u32 |= (CPU_no == S514_CPU_A) ?
-                PCI_ENABLE_IRQ_CPU_A : PCI_ENABLE_IRQ_CPU_B;
-        pci_write_config_dword(pci_dev, PCI_INT_CONFIG, ut_u32);
-
-	printk(KERN_INFO "%s: IRQ %d allocated to the S514 card\n",
-		modname, hw->irq);
-
-	/* map the physical PCI memory to virtual memory */
-	hw->dpmbase = ioremap((unsigned long)S514_mem_base_addr,
-		(unsigned long)MAX_SIZEOF_S514_MEMORY);
-    	/* map the physical control register memory to virtual memory */
-	hw->vector = (unsigned long)ioremap(
-		(unsigned long)(S514_mem_base_addr + S514_CTRL_REG_BYTE),
-		(unsigned long)16);
-     
-        if(!hw->dpmbase || !hw->vector) {
-		printk(KERN_INFO "%s: PCI virtual memory allocation failed\n",
-			modname);
-                return 0;
-	}
-
-	/* halt the adapter */
-	writeb (S514_CPU_HALT, hw->vector);	
-
-	return 1;
-}
-
-/*============================================================================
- * Find the S514 PCI adapter in the PCI bus.
- *      Return the number of S514 adapters found (0 if no adapter found).
- */
-static int find_s514_adapter(sdlahw_t* hw, char find_first_S514_card)
-{
-        unsigned char slot_no;
-        int number_S514_cards = 0;
-	char S514_found_in_slot = 0;
-        u16 PCI_subsys_vendor;
-
-        struct pci_dev *pci_dev = NULL;
- 
-       slot_no = hw->S514_slot_no;
-  
-	while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
-        	!= NULL) {
-                
-		pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
-                        &PCI_subsys_vendor);
-                
-		if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
-                	continue;
-        	
-		hw->pci_dev = pci_dev;
-		
-		if(find_first_S514_card)
-			return(1);
-		
-                number_S514_cards ++;
-                
-		printk(KERN_INFO
-			"%s: S514 card found, slot #%d (devfn 0x%X)\n",
-                        modname, ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
-			pci_dev->devfn);
-		
-		if (hw->auto_pci_cfg){
-			hw->S514_slot_no = ((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK);
-			slot_no = hw->S514_slot_no;
-			
-		}else if (((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK) == slot_no){
-                        S514_found_in_slot = 1;
-                        break;
-                }
-        }
-
-	/* if no S514 adapter has been found, then exit */
-        if (!number_S514_cards) {
-                printk(KERN_INFO "%s: Error, no S514 adapters found\n", modname);
-                return 0;
-        }
-        /* if more than one S514 card has been found, then the user must have */        /* defined a slot number so that the correct adapter is used */
-        else if ((number_S514_cards > 1) && hw->auto_pci_cfg) {
-                printk(KERN_INFO "%s: Error, PCI Slot autodetect Failed! \n"
-				 "%s:        More than one S514 adapter found.\n"
-				 "%s:        Disable the Autodetect feature and supply\n"
-				 "%s:        the PCISLOT numbers for each card.\n",
-                        modname,modname,modname,modname);
-                return 0;
-        }
-        /* if the user has specified a slot number and the S514 adapter has */
-        /* not been found in that slot, then exit */
-        else if (!hw->auto_pci_cfg && !S514_found_in_slot) {
-                printk(KERN_INFO
-			"%s: Error, S514 card not found in specified slot #%d\n",
-                        modname, slot_no);
-                return 0;
-        }
-
-	return (number_S514_cards);
-}
-
-
-
-/******* Miscellaneous ******************************************************/
-
-/*============================================================================
- * Calibrate SDLA memory access delay.
- * Count number of idle loops made within 1 second and then calculate the
- * number of loops that should be made to achive desired delay.
- */
-static int calibrate_delay (int mks)
-{
-	unsigned int delay;
-	unsigned long stop;
-
-	for (delay = 0, stop = SYSTEM_TICK + HZ; SYSTEM_TICK < stop; ++delay);
-	return (delay/(1000000L/mks) + 1);
-}
-
-/*============================================================================
- * Get option's index into the options list.
- *	Return option's index (1 .. N) or zero if option is invalid.
- */
-static int get_option_index (unsigned* optlist, unsigned optval)
-{
-	int i;
-
-	for (i = 1; i <= optlist[0]; ++i)
-		if ( optlist[i] == optval)
-			return i;
-	return 0;
-}
-
-/*============================================================================
- * Check memory region to see if it's available. 
- * Return:	0	ok.
- */
-static unsigned check_memregion (void* ptr, unsigned len)
-{
-	volatile unsigned char* p = ptr;
-
-        for (; len && (readb (p) == 0xFF); --len, ++p) {
-                writeb (0, p);          /* attempt to write 0 */
-                if (readb(p) != 0xFF) { /* still has to read 0xFF */
-                        writeb (0xFF, p);/* restore original value */
-                        break;          /* not good */
-                }
-        }
-
-	return len;
-}
-
-/*============================================================================
- * Test memory region.
- * Return:	size of the region that passed the test.
- * Note:	Region size must be multiple of 2 !
- */
-static unsigned test_memregion (void* ptr, unsigned len)
-{
-	volatile unsigned short* w_ptr;
-	unsigned len_w = len >> 1;	/* region len in words */
-	unsigned i;
-
-        for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
-                writew (0xAA55, w_ptr);
-        
-	for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
-                if (readw (w_ptr) != 0xAA55) {
-                        len_w = i;
-                        break;
-                }
-
-        for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
-                writew (0x55AA, w_ptr);
-        
-        for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
-                if (readw(w_ptr) != 0x55AA) {
-                        len_w = i;
-                        break;
-                }
-        
-        for (i = 0, w_ptr = ptr; i < len_w; ++i, ++w_ptr)
-		writew (0, w_ptr);
-
-        return len_w << 1;
-}
-
-/*============================================================================
- * Calculate 16-bit CRC using CCITT polynomial.
- */
-static unsigned short checksum (unsigned char* buf, unsigned len)
-{
-	unsigned short crc = 0;
-	unsigned mask, flag;
-
-	for (; len; --len, ++buf) {
-		for (mask = 0x80; mask; mask >>= 1) {
-			flag = (crc & 0x8000);
-			crc <<= 1;
-			crc |= ((*buf & mask) ? 1 : 0);
-			if (flag) crc ^= 0x1021;
-		}
-	}
-	return crc;
-}
-
-static int init_pci_slot(sdlahw_t *hw)
-{
-
-	u32 int_status;
-	int volatile found=0;
-	int i=0;
-
-	/* Check if this is a very first load for a specific
-         * pci card. If it is, clear the interrput bits, and
-         * set the flag indicating that this card was initialized.
-	 */
-	
-	for (i=0; (i<MAX_S514_CARDS) && !found; i++){
-		if (pci_slot_ar[i] == hw->S514_slot_no){
-			found=1;
-			break;
-		}
-		if (pci_slot_ar[i] == 0xFF){
-			break;
-		}
-	}
-
-	if (!found){
-		read_S514_int_stat(hw,&int_status);
-		S514_intack(hw,int_status);
-		if (i == MAX_S514_CARDS){
-			printk(KERN_INFO "%s: Critical Error !!!\n",modname);
-			printk(KERN_INFO 
-				"%s: Number of Sangoma PCI cards exceeded maximum limit.\n",
-					modname);
-			printk(KERN_INFO "Please contact Sangoma Technologies\n");
-			return 1;
-		}
-		pci_slot_ar[i] = hw->S514_slot_no;
-	}
-	return 0;
-}
-
-static int pci_probe(sdlahw_t *hw)
-{
-
-        unsigned char slot_no;
-        int number_S514_cards = 0;
-        u16 PCI_subsys_vendor;
-	u16 PCI_card_type;
-
-        struct pci_dev *pci_dev = NULL;
-	struct pci_bus *bus = NULL;
- 
-       slot_no = 0;
-  
-	while ((pci_dev = pci_find_device(V3_VENDOR_ID, V3_DEVICE_ID, pci_dev))
-        	!= NULL) {
-		
-                pci_read_config_word(pci_dev, PCI_SUBSYS_VENDOR_WORD,
-                        &PCI_subsys_vendor);
-		
-                if(PCI_subsys_vendor != SANGOMA_SUBSYS_VENDOR)
-                	continue;
-
-		pci_read_config_word(pci_dev, PCI_CARD_TYPE,
-                        &PCI_card_type);
-	
-		bus = pci_dev->bus;
-		
-		/* A dual cpu card can support up to 4 physical connections,
-		 * where a single cpu card can support up to 2 physical
-		 * connections.  The FT1 card can only support a single 
-		 * connection, however we cannot distinguish between a Single
-		 * CPU card and an FT1 card. */
-		if (PCI_card_type == S514_DUAL_CPU){
-                	number_S514_cards += 4;
-			 printk(KERN_INFO
-				"wanpipe: S514-PCI card found, cpu(s) 2, bus #%d, slot #%d, irq #%d\n",
-                        	bus->number,((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
-				pci_dev->irq);
-		}else{
-			number_S514_cards += 2;
-			printk(KERN_INFO
-				"wanpipe: S514-PCI card found, cpu(s) 1, bus #%d, slot #%d, irq #%d\n",
-                        	bus->number,((pci_dev->devfn >> 3) & PCI_DEV_SLOT_MASK),
-				pci_dev->irq);
-		}
-        }
-
-	return number_S514_cards;
-
-}
-
-
-
-EXPORT_SYMBOL(wanpipe_hw_probe);
-
-unsigned wanpipe_hw_probe(void)
-{
-	sdlahw_t hw;
-	unsigned* opt = s508_port_options; 
-	unsigned cardno=0;
-	int i;
-	
-	memset(&hw, 0, sizeof(hw));
-	
-	for (i = 1; i <= opt[0]; i++) {
-		if (detect_s508(opt[i])){
-			/* S508 card can support up to two physical links */
-			cardno+=2;
-			printk(KERN_INFO "wanpipe: S508-ISA card found, port 0x%x\n",opt[i]);
-		}
-	}
-
-      #ifdef CONFIG_PCI
-	hw.S514_slot_no = 0;
-	cardno += pci_probe(&hw);
-      #else
-	printk(KERN_INFO "wanpipe: Warning, Kernel not compiled for PCI support!\n");
-	printk(KERN_INFO "wanpipe: PCI Hardware Probe Failed!\n");
-      #endif
-
-	return cardno;
-}
-
-/****** End *****************************************************************/
diff --git a/drivers/net/wan/sdlamain.c b/drivers/net/wan/sdlamain.c
deleted file mode 100644
index 7a8b22a..0000000
--- a/drivers/net/wan/sdlamain.c
+++ /dev/null
@@ -1,1346 +0,0 @@
-/****************************************************************************
-* sdlamain.c	WANPIPE(tm) Multiprotocol WAN Link Driver.  Main module.
-*
-* Author:	Nenad Corbic	<ncorbic@sangoma.com>
-*		Gideon Hack	
-*
-* Copyright:	(c) 1995-2000 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.
-* ============================================================================
-* Dec 22, 2000  Nenad Corbic	Updated for 2.4.X kernels.
-* 				Removed the polling routine.
-* Nov 13, 2000  Nenad Corbic	Added hw probing on module load and dynamic
-* 				device allocation. 
-* Nov 7,  2000  Nenad Corbic	Fixed the Multi-Port PPP for kernels
-*                               2.2.16 and above.
-* Aug 2,  2000  Nenad Corbic	Block the Multi-Port PPP from running on
-*  			        kernels 2.2.16 or greater.  The SyncPPP 
-*  			        has changed.
-* Jul 25, 2000  Nenad Corbic	Updated the Piggiback support for MultPPPP.
-* Jul 13, 2000	Nenad Corbic	Added Multi-PPP support.
-* Feb 02, 2000  Nenad Corbic    Fixed up piggyback probing and selection.
-* Sep 23, 1999  Nenad Corbic    Added support for SMP
-* Sep 13, 1999  Nenad Corbic	Each port is treated as a separate device.
-* Jun 02, 1999  Gideon Hack     Added support for the S514 adapter.
-*				Updates for Linux 2.2.X kernels.
-* Sep 17, 1998	Jaspreet Singh	Updated for 2.1.121+ kernel
-* Nov 28, 1997	Jaspreet Singh	Changed DRV_RELEASE to 1
-* Nov 10, 1997	Jaspreet Singh	Changed sti() to restore_flags();
-* Nov 06, 1997 	Jaspreet Singh	Changed DRV_VERSION to 4 and DRV_RELEASE to 0
-* Oct 20, 1997 	Jaspreet Singh	Modified sdla_isr routine so that card->in_isr
-*				assignments are taken out and placed in the
-*				sdla_ppp.c, sdla_fr.c and sdla_x25.c isr
-*				routines. Took out 'wandev->tx_int_enabled' and
-*				replaced it with 'wandev->enable_tx_int'. 
-* May 29, 1997	Jaspreet Singh	Flow Control Problem
-*				added "wandev->tx_int_enabled=1" line in the
-*				init module. This line initializes the flag for 
-*				preventing Interrupt disabled with device set to
-*				busy
-* Jan 15, 1997	Gene Kozin	Version 3.1.0
-*				 o added UDP management stuff
-* Jan 02, 1997	Gene Kozin	Initial version.
-*****************************************************************************/
-
-#include <linux/config.h>	/* OS configuration options */
-#include <linux/stddef.h>	/* offsetof(), etc. */
-#include <linux/errno.h>	/* return codes */
-#include <linux/string.h>	/* inline memset(), etc. */
-#include <linux/init.h>
-#include <linux/slab.h>	/* kmalloc(), kfree() */
-#include <linux/kernel.h>	/* printk(), and other useful stuff */
-#include <linux/module.h>	/* support for loadable modules */
-#include <linux/ioport.h>	/* request_region(), release_region() */
-#include <linux/wanrouter.h>	/* WAN router definitions */
-#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
-#include <linux/rcupdate.h>
-
-#include <linux/in.h>
-#include <asm/io.h>		/* phys_to_virt() */
-#include <linux/pci.h>
-#include <linux/sdlapci.h>
-#include <linux/if_wanpipe_common.h>
-
-#include <asm/uaccess.h>	/* kernel <-> user copy */
-#include <linux/inetdevice.h>
-
-#include <linux/ip.h>
-#include <net/route.h>
- 
-#define KMEM_SAFETYZONE 8
-
-
-#ifndef CONFIG_WANPIPE_FR
-  #define wpf_init(a,b) (-EPROTONOSUPPORT) 
-#endif
-
-#ifndef CONFIG_WANPIPE_CHDLC
- #define wpc_init(a,b) (-EPROTONOSUPPORT) 
-#endif
-
-#ifndef CONFIG_WANPIPE_X25
- #define wpx_init(a,b) (-EPROTONOSUPPORT) 
-#endif
- 
-#ifndef CONFIG_WANPIPE_PPP
- #define wpp_init(a,b) (-EPROTONOSUPPORT) 
-#endif
-
-#ifndef CONFIG_WANPIPE_MULTPPP 
- #define wsppp_init(a,b) (-EPROTONOSUPPORT) 
-#endif
- 
- 
-/***********FOR DEBUGGING PURPOSES*********************************************
-static void * dbg_kmalloc(unsigned int size, int prio, int line) {
-	int i = 0;
-	void * v = kmalloc(size+sizeof(unsigned int)+2*KMEM_SAFETYZONE*8,prio);
-	char * c1 = v;	
-	c1 += sizeof(unsigned int);
-	*((unsigned int *)v) = size;
-
-	for (i = 0; i < KMEM_SAFETYZONE; i++) {
-		c1[0] = 'D'; c1[1] = 'E'; c1[2] = 'A'; c1[3] = 'D';
-		c1[4] = 'B'; c1[5] = 'E'; c1[6] = 'E'; c1[7] = 'F';
-		c1 += 8;
-	}
-	c1 += size;
-	for (i = 0; i < KMEM_SAFETYZONE; i++) {
-		c1[0] = 'M'; c1[1] = 'U'; c1[2] = 'N'; c1[3] = 'G';
-		c1[4] = 'W'; c1[5] = 'A'; c1[6] = 'L'; c1[7] = 'L';
-		c1 += 8;
-	}
-	v = ((char *)v) + sizeof(unsigned int) + KMEM_SAFETYZONE*8;
-	printk(KERN_INFO "line %d  kmalloc(%d,%d) = %p\n",line,size,prio,v);
-	return v;
-}
-static void dbg_kfree(void * v, int line) {
-	unsigned int * sp = (unsigned int *)(((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8));
-	unsigned int size = *sp;
-	char * c1 = ((char *)v) - KMEM_SAFETYZONE*8;
-	int i = 0;
-	for (i = 0; i < KMEM_SAFETYZONE; i++) {
-		if (   c1[0] != 'D' || c1[1] != 'E' || c1[2] != 'A' || c1[3] != 'D'
-		    || c1[4] != 'B' || c1[5] != 'E' || c1[6] != 'E' || c1[7] != 'F') {
-			printk(KERN_INFO "kmalloced block at %p has been corrupted (underrun)!\n",v);
-			printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
-			                c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
-		}
-		c1 += 8;
-	}
-	c1 += size;
-	for (i = 0; i < KMEM_SAFETYZONE; i++) {
-		if (   c1[0] != 'M' || c1[1] != 'U' || c1[2] != 'N' || c1[3] != 'G'
-		    || c1[4] != 'W' || c1[5] != 'A' || c1[6] != 'L' || c1[7] != 'L'
-		   ) {
-			printk(KERN_INFO "kmalloced block at %p has been corrupted (overrun):\n",v);
-			printk(KERN_INFO " %4x: %2x %2x %2x %2x %2x %2x %2x %2x\n", i*8,
-			                c1[0],c1[1],c1[2],c1[3],c1[4],c1[5],c1[6],c1[7] );
-		}
-		c1 += 8;
-	}
-	printk(KERN_INFO "line %d  kfree(%p)\n",line,v);
-	v = ((char *)v) - (sizeof(unsigned int) + KMEM_SAFETYZONE*8);
-	kfree(v);
-}
-
-#define kmalloc(x,y) dbg_kmalloc(x,y,__LINE__)
-#define kfree(x) dbg_kfree(x,__LINE__)
-******************************************************************************/
-
-
-
-/****** Defines & Macros ****************************************************/
-
-#ifdef	_DEBUG_
-#define	STATIC
-#else
-#define	STATIC		static
-#endif
-
-#define	DRV_VERSION	5		/* version number */
-#define	DRV_RELEASE	0		/* release (minor version) number */
-#define	MAX_CARDS	16		/* max number of adapters */
-
-#ifndef	CONFIG_WANPIPE_CARDS		/* configurable option */
-#define	CONFIG_WANPIPE_CARDS 1
-#endif
-
-#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 */
-/****** Function Prototypes *************************************************/
-
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
- 
-/* WAN link driver entry points */
-static int setup(struct wan_device* wandev, wandev_conf_t* conf);
-static int shutdown(struct wan_device* wandev);
-static int ioctl(struct wan_device* wandev, unsigned cmd, unsigned long arg);
-
-/* IOCTL handlers */
-static int ioctl_dump	(sdla_t* card, sdla_dump_t* u_dump);
-static int ioctl_exec	(sdla_t* card, sdla_exec_t* u_exec, int);
-
-/* Miscellaneous functions */
-STATIC irqreturn_t sdla_isr	(int irq, void* dev_id, struct pt_regs *regs);
-static void release_hw  (sdla_t *card);
-
-static int check_s508_conflicts (sdla_t* card,wandev_conf_t* conf, int*);
-static int check_s514_conflicts (sdla_t* card,wandev_conf_t* conf, int*);
-
-
-/****** Global Data **********************************************************
- * Note: All data must be explicitly initialized!!!
- */
-
-/* private data */
-static char drvname[]	= "wanpipe";
-static char fullname[]	= "WANPIPE(tm) Multiprotocol Driver";
-static char copyright[]	= "(c) 1995-2000 Sangoma Technologies Inc.";
-static int ncards; 
-static sdla_t* card_array;		/* adapter data space */
-
-/* Wanpipe's own workqueue, used for all API's.
- * All protocol specific tasks will be inserted
- * into the "wanpipe_wq" workqueue. 
-
- * The kernel workqueue mechanism will execute
- * all pending tasks in the "wanpipe_wq" workqueue.
- */
-
-struct workqueue_struct *wanpipe_wq;
-DECLARE_WORK(wanpipe_work, NULL, NULL);
-
-static int wanpipe_bh_critical;
-
-/******* Kernel Loadable Module Entry Points ********************************/
-
-/*============================================================================
- * Module 'insert' entry point.
- * o print announcement
- * o allocate adapter data space
- * o initialize static data
- * o register all cards with WAN router
- * o calibrate SDLA shared memory access delay.
- *
- * Return:	0	Ok
- *		< 0	error.
- * Context:	process
- */
- 
-static int __init wanpipe_init(void)
-{
-	int cnt, err = 0;
-
-	printk(KERN_INFO "%s v%u.%u %s\n",
-		fullname, DRV_VERSION, DRV_RELEASE, copyright);
-
-	wanpipe_wq = create_workqueue("wanpipe_wq");
-	if (!wanpipe_wq)
-		return -ENOMEM;
-
-	/* Probe for wanpipe cards and return the number found */
-	printk(KERN_INFO "wanpipe: Probing for WANPIPE hardware.\n");
-	ncards = wanpipe_hw_probe();
-	if (ncards){
-		printk(KERN_INFO "wanpipe: Allocating maximum %i devices: wanpipe%i - wanpipe%i.\n",ncards,1,ncards);
-	}else{
-		printk(KERN_INFO "wanpipe: No S514/S508 cards found, unloading modules!\n");
-		destroy_workqueue(wanpipe_wq);
-		return -ENODEV;
-	}
-	
-	/* Verify number of cards and allocate adapter data space */
-	card_array = kmalloc(sizeof(sdla_t) * ncards, GFP_KERNEL);
-	if (card_array == NULL) {
-		destroy_workqueue(wanpipe_wq);
-		return -ENOMEM;
-	}
-
-	memset(card_array, 0, sizeof(sdla_t) * ncards);
-
-	/* Register adapters with WAN router */
-	for (cnt = 0; cnt < ncards; ++ cnt) {
-		sdla_t* card = &card_array[cnt];
-		struct wan_device* wandev = &card->wandev;
-
-		card->next = NULL;
-		sprintf(card->devname, "%s%d", drvname, cnt + 1);
-		wandev->magic    = ROUTER_MAGIC;
-		wandev->name     = card->devname;
-		wandev->private  = card;
-		wandev->enable_tx_int = 0;
-		wandev->setup    = &setup;
-		wandev->shutdown = &shutdown;
-		wandev->ioctl    = &ioctl;
-		err = register_wan_device(wandev);
-		if (err) {
-			printk(KERN_INFO
-				"%s: %s registration failed with error %d!\n",
-				drvname, card->devname, err);
-			break;
-		}
-	}
-	if (cnt){
-		ncards = cnt;	/* adjust actual number of cards */
-	}else {
-		kfree(card_array);
-		destroy_workqueue(wanpipe_wq);
-		printk(KERN_INFO "IN Init Module: NO Cards registered\n");
-		err = -ENODEV;
-	}
-
-	return err;
-}
-
-/*============================================================================
- * Module 'remove' entry point.
- * o unregister all adapters from the WAN router
- * o release all remaining system resources
- */
-static void __exit wanpipe_cleanup(void)
-{
-	int i;
-
-	if (!ncards)
-		return;
-		
-	for (i = 0; i < ncards; ++i) {
-		sdla_t* card = &card_array[i];
-		unregister_wan_device(card->devname);
-	}
-	destroy_workqueue(wanpipe_wq);
-	kfree(card_array);
-
-	printk(KERN_INFO "\nwanpipe: WANPIPE Modules Unloaded.\n");
-}
-
-module_init(wanpipe_init);
-module_exit(wanpipe_cleanup);
-
-/******* WAN Device Driver Entry Points *************************************/
-
-/*============================================================================
- * Setup/configure WAN link driver.
- * o check adapter state
- * o make sure firmware is present in configuration
- * o make sure I/O port and IRQ are specified
- * o make sure I/O region is available
- * o allocate interrupt vector
- * o setup SDLA hardware
- * o call appropriate routine to perform protocol-specific initialization
- * o mark I/O region as used
- * o if this is the first active card, then schedule background task
- *
- * This function is called when router handles ROUTER_SETUP IOCTL. The
- * configuration structure is in kernel memory (including extended data, if
- * any).
- */
- 
-static int setup(struct wan_device* wandev, wandev_conf_t* conf)
-{
-	sdla_t* card;
-	int err = 0;
-	int irq=0;
-
-	/* Sanity checks */
-	if ((wandev == NULL) || (wandev->private == NULL) || (conf == NULL)){
-		printk(KERN_INFO 
-		      "%s: Failed Sdlamain Setup wandev %u, card %u, conf %u !\n",
-		      wandev->name,
-		      (unsigned int)wandev,(unsigned int)wandev->private,
-		      (unsigned int)conf); 
-		return -EFAULT;
-	}
-
-	printk(KERN_INFO "%s: Starting WAN Setup\n", wandev->name);
-
-	card = wandev->private;
-	if (wandev->state != WAN_UNCONFIGURED){
-		printk(KERN_INFO "%s: failed sdlamain setup, busy!\n",
-			wandev->name);
-		return -EBUSY;		/* already configured */
-	}
-
-	printk(KERN_INFO "\nProcessing WAN device %s...\n", wandev->name);
-
-	/* Initialize the counters for each wandev 
-	 * Used for counting number of times new_if and 
-         * del_if get called.
-	 */
-	wandev->del_if_cnt = 0;
-	wandev->new_if_cnt = 0;
-	wandev->config_id  = conf->config_id;
-
-	if (!conf->data_size || (conf->data == NULL)) {
-		printk(KERN_INFO
-			"%s: firmware not found in configuration data!\n",
-			wandev->name);
-		return -EINVAL;
-	}
-
-	/* Check for resource conflicts and setup the
-	 * card for piggibacking if necessary */
-	if(!conf->S514_CPU_no[0]) {
-		if ((err=check_s508_conflicts(card,conf,&irq)) != 0){
-			return err;
-		}
-	}else {
-		if ((err=check_s514_conflicts(card,conf,&irq)) != 0){
-			return err;
-		}
-	}
-
-	/* If the current card has already been configured
-         * or it's a piggyback card, do not try to allocate
-         * resources.
-	 */
-	if (!card->wandev.piggyback && !card->configured){
-
-		/* Configure hardware, load firmware, etc. */
-		memset(&card->hw, 0, sizeof(sdlahw_t));
-
-		/* for an S514 adapter, pass the CPU number and the slot number read */
-		/* from 'router.conf' to the 'sdla_setup()' function via the 'port' */
-		/* parameter */
-		if (conf->S514_CPU_no[0]){
-
-			card->hw.S514_cpu_no[0] = conf->S514_CPU_no[0];
-			card->hw.S514_slot_no = conf->PCI_slot_no;
-			card->hw.auto_pci_cfg = conf->auto_pci_cfg;
-
-			if (card->hw.auto_pci_cfg == WANOPT_YES){
-				printk(KERN_INFO "%s: Setting CPU to %c and Slot to Auto\n",
-				card->devname, card->hw.S514_cpu_no[0]);
-			}else{
-				printk(KERN_INFO "%s: Setting CPU to %c and Slot to %i\n",
-				card->devname, card->hw.S514_cpu_no[0], card->hw.S514_slot_no);
-			}
-
-		}else{
-			/* 508 Card io port and irq initialization */
-			card->hw.port = conf->ioport;
-			card->hw.irq = (conf->irq == 9) ? 2 : conf->irq;
-		}
-
-
-		/* Compute the virtual address of the card in kernel space */
-		if(conf->maddr){
-			card->hw.dpmbase = phys_to_virt(conf->maddr);
-		}else{	
-			card->hw.dpmbase = (void *)conf->maddr;
-		}
-			
-		card->hw.dpmsize = SDLA_WINDOWSIZE;
-		
-		/* set the adapter type if using an S514 adapter */
-		card->hw.type = (conf->S514_CPU_no[0]) ? SDLA_S514 : conf->hw_opt[0]; 
-		card->hw.pclk = conf->hw_opt[1];
-
-		err = sdla_setup(&card->hw, conf->data, conf->data_size);
-		if (err){
-			printk(KERN_INFO "%s: Hardware setup Failed %i\n",
-					card->devname,err);
-			return err;
-		}
-
-	        if(card->hw.type != SDLA_S514)
-			irq = (conf->irq == 2) ? 9 : conf->irq; /* IRQ2 -> IRQ9 */
-		else
-			irq = card->hw.irq;
-
-		/* request an interrupt vector - note that interrupts may be shared */
-		/* when using the S514 PCI adapter */
-		
-       		if(request_irq(irq, sdla_isr, 
-		      (card->hw.type == SDLA_S514) ? SA_SHIRQ : 0, 
-		       wandev->name, card)){
-
-			printk(KERN_INFO "%s: Can't reserve IRQ %d!\n", wandev->name, irq);
-			return -EINVAL;
-		}
-
-	}else{
-		printk(KERN_INFO "%s: Card Configured %lu or Piggybacking %i!\n",
-			wandev->name,card->configured,card->wandev.piggyback);
-	} 
-
-
-	if (!card->configured){
-
-		/* Initialize the Spin lock */
-		printk(KERN_INFO "%s: Initializing for SMP\n",wandev->name);
-
-		/* Piggyback spin lock has already been initialized,
-		 * in check_s514/s508_conflicts() */
-		if (!card->wandev.piggyback){
-			spin_lock_init(&card->wandev.lock);
-		}
-		
-		/* Intialize WAN device data space */
-		wandev->irq       = irq;
-		wandev->dma       = 0;
-		if(card->hw.type != SDLA_S514){ 
-			wandev->ioport = card->hw.port;
-		}else{
-			wandev->S514_cpu_no[0] = card->hw.S514_cpu_no[0];
-			wandev->S514_slot_no = card->hw.S514_slot_no;
-		}
-		wandev->maddr     = (unsigned long)card->hw.dpmbase;
-		wandev->msize     = card->hw.dpmsize;
-		wandev->hw_opt[0] = card->hw.type;
-		wandev->hw_opt[1] = card->hw.pclk;
-		wandev->hw_opt[2] = card->hw.memory;
-		wandev->hw_opt[3] = card->hw.fwid;
-	}
-
-	/* Protocol-specific initialization */
-	switch (card->hw.fwid) {
-
-	case SFID_X25_502:
-	case SFID_X25_508:
-		printk(KERN_INFO "%s: Starting X.25 Protocol Init.\n",
-				card->devname);
-		err = wpx_init(card, conf);
-		break;
-	case SFID_FR502:
-	case SFID_FR508:
-		printk(KERN_INFO "%s: Starting Frame Relay Protocol Init.\n",
-				card->devname);
-		err = wpf_init(card, conf);
-		break;
-	case SFID_PPP502:
-	case SFID_PPP508:
-		printk(KERN_INFO "%s: Starting PPP Protocol Init.\n",
-				card->devname);
-		err = wpp_init(card, conf);
-		break;
-		
-	case SFID_CHDLC508:
-	case SFID_CHDLC514:
-		if (conf->ft1){		
-			printk(KERN_INFO "%s: Starting FT1 CSU/DSU Config Driver.\n",
-				card->devname);
-			err = wpft1_init(card, conf);
-			break;
-			
-		}else if (conf->config_id == WANCONFIG_MPPP){
-			printk(KERN_INFO "%s: Starting Multi-Port PPP Protocol Init.\n",
-					card->devname);
-			err = wsppp_init(card,conf);
-			break;
-
-		}else{
-			printk(KERN_INFO "%s: Starting CHDLC Protocol Init.\n",
-					card->devname);
-			err = wpc_init(card, conf);
-			break;
-		}
-	default:
-		printk(KERN_INFO "%s: Error, Firmware is not supported %X %X!\n",
-			wandev->name,card->hw.fwid,SFID_CHDLC508);
-		err = -EPROTONOSUPPORT;
-	}
-
-	if (err != 0){
-		if (err == -EPROTONOSUPPORT){
-			printk(KERN_INFO 
-				"%s: Error, Protocol selected has not been compiled!\n",
-					card->devname);
-			printk(KERN_INFO 
-				"%s:        Re-configure the kernel and re-build the modules!\n",
-					card->devname);
-		}
-		
-		release_hw(card);
-		wandev->state = WAN_UNCONFIGURED;
-		return err;
-	}
-
-
-  	/* Reserve I/O region and schedule background task */
-        if(card->hw.type != SDLA_S514 && !card->wandev.piggyback)
-		if (!request_region(card->hw.port, card->hw.io_range, 
-				wandev->name)) {
-			printk(KERN_WARNING "port 0x%04x busy\n", card->hw.port);
-			release_hw(card);
-			wandev->state = WAN_UNCONFIGURED;
-			return -EBUSY;
-	  }
-
-	/* Only use the polling routine for the X25 protocol */
-	
-	card->wandev.critical=0;
-	return 0;
-}
-
-/*================================================================== 
- * configure_s508_card
- * 
- * For a S508 adapter, check for a possible configuration error in that
- * we are loading an adapter in the same IO port as a previously loaded S508
- * card.
- */ 
-
-static int check_s508_conflicts (sdla_t* card,wandev_conf_t* conf, int *irq)
-{
-	unsigned long smp_flags;
-	int i;
-	
-	if (conf->ioport <= 0) {
-		printk(KERN_INFO
-		"%s: can't configure without I/O port address!\n",
-		card->wandev.name);
-		return -EINVAL;
-	}
-
-	if (conf->irq <= 0) {
-		printk(KERN_INFO "%s: can't configure without IRQ!\n",
-		card->wandev.name);
-		return -EINVAL;
-	}
-
-	if (test_bit(0,&card->configured))
-		return 0;
-
-
-	/* Check for already loaded card with the same IO port and IRQ 
-	 * If found, copy its hardware configuration and use its
-	 * resources (i.e. piggybacking)
-	 */
-	
-	for (i = 0; i < ncards; i++) {
-		sdla_t *nxt_card = &card_array[i];
-
-		/* Skip the current card ptr */
-		if (nxt_card == card)	
-			continue;
-
-
-		/* Find a card that is already configured with the
-		 * same IO Port */
-		if ((nxt_card->hw.type == SDLA_S508) &&
-		    (nxt_card->hw.port == conf->ioport) && 
-		    (nxt_card->next == NULL)){
-			
-			/* We found a card the card that has same configuration
-			 * as us. This means, that we must setup this card in 
-			 * piggibacking mode. However, only CHDLC and MPPP protocol
-			 * support this setup */
-		
-			if ((conf->config_id == WANCONFIG_CHDLC || 
-			     conf->config_id == WANCONFIG_MPPP) &&
-			    (nxt_card->wandev.config_id == WANCONFIG_CHDLC || 
-			     nxt_card->wandev.config_id == WANCONFIG_MPPP)){ 
-				
-				*irq = nxt_card->hw.irq;
-				memcpy(&card->hw, &nxt_card->hw, sizeof(sdlahw_t));
-			
-				/* The master could already be running, we must
-				 * set this as a critical area */
-				lock_adapter_irq(&nxt_card->wandev.lock, &smp_flags);
-
-				nxt_card->next = card;
-				card->next = nxt_card;
-
-				card->wandev.piggyback = WANOPT_YES;
-
-				/* We must initialise the piggiback spin lock here
-				 * since isr will try to lock card->next if it
-				 * exists */
-				spin_lock_init(&card->wandev.lock);
-				
-				unlock_adapter_irq(&nxt_card->wandev.lock, &smp_flags);
-				break;
-			}else{
-				/* Trying to run piggibacking with a wrong protocol */
-				printk(KERN_INFO "%s: ERROR: Resource busy, ioport: 0x%x\n"
-						 "%s:        This protocol doesn't support\n"
-						 "%s:        multi-port operation!\n",
-						 card->devname,nxt_card->hw.port,
-						 card->devname,card->devname);
-				return -EEXIST;
-			}
-		}
-	}
-	
-
-	/* Make sure I/O port region is available only if we are the
-	 * master device.  If we are running in piggybacking mode, 
-	 * we will use the resources of the master card. */
-	if (!card->wandev.piggyback) {
-		struct resource *rr =
-			request_region(conf->ioport, SDLA_MAXIORANGE, "sdlamain");
-		release_region(conf->ioport, SDLA_MAXIORANGE);
-
-		if (!rr) {
-			printk(KERN_INFO
-				"%s: I/O region 0x%X - 0x%X is in use!\n",
-				card->wandev.name, conf->ioport,
-				conf->ioport + SDLA_MAXIORANGE - 1);
-			return -EINVAL;
-		}
-	}
-
-	return 0;
-}
-
-/*================================================================== 
- * configure_s514_card
- * 
- * For a S514 adapter, check for a possible configuration error in that
- * we are loading an adapter in the same slot as a previously loaded S514
- * card.
- */ 
-
-
-static int check_s514_conflicts(sdla_t* card,wandev_conf_t* conf, int *irq)
-{
-	unsigned long smp_flags;
-	int i;
-	
-	if (test_bit(0,&card->configured))
-		return 0;
-
-	
-	/* Check for already loaded card with the same IO port and IRQ 
-	 * If found, copy its hardware configuration and use its
-	 * resources (i.e. piggybacking)
-	 */
-
-	for (i = 0; i < ncards; i ++) {
-	
-		sdla_t* nxt_card = &card_array[i];
-		if(nxt_card == card)
-			continue;
-		
-		if((nxt_card->hw.type == SDLA_S514) &&
-		   (nxt_card->hw.S514_slot_no == conf->PCI_slot_no) &&
-		   (nxt_card->hw.S514_cpu_no[0] == conf->S514_CPU_no[0])&&
-		   (nxt_card->next == NULL)){
-
-
-			if ((conf->config_id == WANCONFIG_CHDLC || 
-			     conf->config_id == WANCONFIG_MPPP) &&
-			    (nxt_card->wandev.config_id == WANCONFIG_CHDLC || 
-			     nxt_card->wandev.config_id == WANCONFIG_MPPP)){ 
-				
-				*irq = nxt_card->hw.irq;
-				memcpy(&card->hw, &nxt_card->hw, sizeof(sdlahw_t));
-	
-				/* The master could already be running, we must
-				 * set this as a critical area */
-				lock_adapter_irq(&nxt_card->wandev.lock,&smp_flags);
-				nxt_card->next = card;
-				card->next = nxt_card;
-
-				card->wandev.piggyback = WANOPT_YES;
-
-				/* We must initialise the piggiback spin lock here
-				 * since isr will try to lock card->next if it
-				 * exists */
-				spin_lock_init(&card->wandev.lock);
-
-				unlock_adapter_irq(&nxt_card->wandev.lock,&smp_flags);
-
-			}else{
-				/* Trying to run piggibacking with a wrong protocol */
-				printk(KERN_INFO "%s: ERROR: Resource busy: CPU %c PCISLOT %i\n"
-						 "%s:        This protocol doesn't support\n"
-						 "%s:        multi-port operation!\n",
-						 card->devname,
-						 conf->S514_CPU_no[0],conf->PCI_slot_no,
-						 card->devname,card->devname);
-				return -EEXIST;
-			}
-		}
-	}
-
-	return 0;
-}
-
-
-
-/*============================================================================
- * Shut down WAN link driver. 
- * o shut down adapter hardware
- * o release system resources.
- *
- * This function is called by the router when device is being unregistered or
- * when it handles ROUTER_DOWN IOCTL.
- */
-static int shutdown(struct wan_device* wandev)
-{
-	sdla_t *card;
-	int err=0;
-	
-	/* sanity checks */
-	if ((wandev == NULL) || (wandev->private == NULL)){
-		return -EFAULT;
-	}
-		
-	if (wandev->state == WAN_UNCONFIGURED){
-		return 0;
-	}
-
-	card = wandev->private;
-
-	if (card->tty_opt){
-		if (card->tty_open){
-			printk(KERN_INFO 
-				"%s: Shutdown Failed: TTY is still open\n",
-				  card->devname);
-			return -EBUSY;
-		}
-	}
-	
-	wandev->state = WAN_UNCONFIGURED;
-
-	set_bit(PERI_CRIT,(void*)&wandev->critical);
-	
-	/* In case of piggibacking, make sure that 
-         * we never try to shutdown both devices at the same
-         * time, because they depend on one another */
-	
-	if (card->disable_comm){
-		card->disable_comm(card);
-	}
-
-	/* Release Resources */
-	release_hw(card);
-
-        /* only free the allocated I/O range if not an S514 adapter */
-	if (wandev->hw_opt[0] != SDLA_S514 && !card->configured){
-              	release_region(card->hw.port, card->hw.io_range);
-	}
-
-	if (!card->configured){
-		memset(&card->hw, 0, sizeof(sdlahw_t));
-	      	if (card->next){
-			memset(&card->next->hw, 0, sizeof(sdlahw_t));
-		}
-	}
-	
-
-	clear_bit(PERI_CRIT,(void*)&wandev->critical);
-	return err;
-}
-
-static void release_hw (sdla_t *card)
-{
-	sdla_t *nxt_card;
-
-	
-	/* Check if next device exists */
-	if (card->next){
-		nxt_card = card->next;
-		/* If next device is down then release resources */
-		if (nxt_card->wandev.state == WAN_UNCONFIGURED){
-			if (card->wandev.piggyback){
-				/* If this device is piggyback then use
-                                 * information of the master device 
-				 */
-				printk(KERN_INFO "%s: Piggyback shutting down\n",card->devname);
-				sdla_down(&card->next->hw);
-       				free_irq(card->wandev.irq, card->next);
-				card->configured = 0;
-				card->next->configured = 0;
-				card->wandev.piggyback = 0;
-			}else{
-				/* Master device shutting down */
-				printk(KERN_INFO "%s: Master shutting down\n",card->devname);
-				sdla_down(&card->hw);
-				free_irq(card->wandev.irq, card);
-				card->configured = 0;
-				card->next->configured = 0;
-			}
-		}else{
-			printk(KERN_INFO "%s: Device still running %i\n",
-				nxt_card->devname,nxt_card->wandev.state);
-
-			card->configured = 1;
-		}
-	}else{
-		printk(KERN_INFO "%s: Master shutting down\n",card->devname);
-		sdla_down(&card->hw);
-       		free_irq(card->wandev.irq, card);
-		card->configured = 0;
-	}
-	return;
-}
-
-
-/*============================================================================
- * Driver I/O control. 
- * o verify arguments
- * o perform requested action
- *
- * This function is called when router handles one of the reserved user
- * IOCTLs.  Note that 'arg' stil points to user address space.
- */
-static int ioctl(struct wan_device* wandev, unsigned cmd, unsigned long arg)
-{
-	sdla_t* card;
-	int err;
-
-	/* sanity checks */
-	if ((wandev == NULL) || (wandev->private == NULL))
-		return -EFAULT;
-	if (wandev->state == WAN_UNCONFIGURED)
-		return -ENODEV;
-
-	card = wandev->private;
-
-	if(card->hw.type != SDLA_S514){
-		disable_irq(card->hw.irq);
-	}
-
-	if (test_bit(SEND_CRIT, (void*)&wandev->critical)) {
-		return -EAGAIN;
-	}
-	
-	switch (cmd) {
-	case WANPIPE_DUMP:
-		err = ioctl_dump(wandev->private, (void*)arg);
-		break;
-
-	case WANPIPE_EXEC:
-		err = ioctl_exec(wandev->private, (void*)arg, cmd);
-		break;
-	default:
-		err = -EINVAL;
-	}
- 
-	return err;
-}
-
-/****** Driver IOCTL Handlers ***********************************************/
-
-/*============================================================================
- * Dump adapter memory to user buffer.
- * o verify request structure
- * o copy request structure to kernel data space
- * o verify length/offset
- * o verify user buffer
- * o copy adapter memory image to user buffer
- *
- * Note: when dumping memory, this routine switches curent dual-port memory
- *	 vector, so care must be taken to avoid racing conditions.
- */
-static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump)
-{
-	sdla_dump_t dump;
-	unsigned winsize;
-	unsigned long oldvec;	/* DPM window vector */
-	unsigned long smp_flags;
-	int err = 0;
-
-	if(copy_from_user((void*)&dump, (void*)u_dump, sizeof(sdla_dump_t)))
-		return -EFAULT;
-		
-	if ((dump.magic != WANPIPE_MAGIC) ||
-	    (dump.offset + dump.length > card->hw.memory))
-		return -EINVAL;
-	
-	winsize = card->hw.dpmsize;
-
-	if(card->hw.type != SDLA_S514) {
-
-		lock_adapter_irq(&card->wandev.lock, &smp_flags);
-		
-                oldvec = card->hw.vector;
-                while (dump.length) {
-			/* current offset */				
-                        unsigned pos = dump.offset % winsize;
-			/* current vector */
-                        unsigned long vec = dump.offset - pos;
-                        unsigned len = (dump.length > (winsize - pos)) ?
-                        	(winsize - pos) : dump.length;
-			/* relocate window */
-                        if (sdla_mapmem(&card->hw, vec) != 0) {
-                                err = -EIO;
-                                break;
-                        }
-			
-                        if(copy_to_user((void *)dump.ptr,
-                                (u8 *)card->hw.dpmbase + pos, len)){ 
-				
-				unlock_adapter_irq(&card->wandev.lock, &smp_flags);
-				return -EFAULT;
-			}
-
-                        dump.length     -= len;
-                        dump.offset     += len;
-                        dump.ptr         = (char*)dump.ptr + len;
-                }
-		
-                sdla_mapmem(&card->hw, oldvec);/* restore DPM window position */
-		unlock_adapter_irq(&card->wandev.lock, &smp_flags);
-        
-	}else {
-
-               if(copy_to_user((void *)dump.ptr,
-			       (u8 *)card->hw.dpmbase + dump.offset, dump.length)){
-			return -EFAULT;
-		}
-	}
-
-	return err;
-}
-
-/*============================================================================
- * Execute adapter firmware command.
- * o verify request structure
- * o copy request structure to kernel data space
- * o call protocol-specific 'exec' function
- */
-static int ioctl_exec (sdla_t* card, sdla_exec_t* u_exec, int cmd)
-{
-	sdla_exec_t exec;
-	int err=0;
-
-	if (card->exec == NULL && cmd == WANPIPE_EXEC){
-		return -ENODEV;
-	}
-
-	if(copy_from_user((void*)&exec, (void*)u_exec, sizeof(sdla_exec_t)))
-		return -EFAULT;
-
-	if ((exec.magic != WANPIPE_MAGIC) || (exec.cmd == NULL))
-		return -EINVAL;
-
-	switch (cmd) {
-		case WANPIPE_EXEC:	
-			err = card->exec(card, exec.cmd, exec.data);
-			break;
-	}	
-	return err;
-}
-
-/******* Miscellaneous ******************************************************/
-
-/*============================================================================
- * SDLA Interrupt Service Routine.
- * o acknowledge SDLA hardware interrupt.
- * o call protocol-specific interrupt service routine, if any.
- */
-STATIC irqreturn_t sdla_isr (int irq, void* dev_id, struct pt_regs *regs)
-{
-#define	card	((sdla_t*)dev_id)
-
-	if(card->hw.type == SDLA_S514) {	/* handle interrrupt on S514 */
-                u32 int_status;
-                unsigned char CPU_no = card->hw.S514_cpu_no[0];
-                unsigned char card_found_for_IRQ;
-		u8 IRQ_count = 0;
-
-		for(;;) {
-
-			read_S514_int_stat(&card->hw, &int_status);
-
-			/* check if the interrupt is for this device */
- 			if(!((unsigned char)int_status &
-				(IRQ_CPU_A | IRQ_CPU_B)))
-                	        return IRQ_HANDLED;
-
-			/* if the IRQ is for both CPUs on the same adapter, */
-			/* then alter the interrupt status so as to handle */
-			/* one CPU at a time */
-			if(((unsigned char)int_status & (IRQ_CPU_A | IRQ_CPU_B))
-				== (IRQ_CPU_A | IRQ_CPU_B)) {
-				int_status &= (CPU_no == S514_CPU_A) ?
-					~IRQ_CPU_B : ~IRQ_CPU_A;
-			}
- 
-			card_found_for_IRQ = 0;
-
-	             	/* check to see that the CPU number for this device */
-			/* corresponds to the interrupt status read */
-                	switch (CPU_no) {
-                        	case S514_CPU_A:
-                                	if((unsigned char)int_status &
-						IRQ_CPU_A)
-                                        card_found_for_IRQ = 1;
-                                break;
-
-	                        case S514_CPU_B:
-        	                        if((unsigned char)int_status &
-						IRQ_CPU_B)
-                                        card_found_for_IRQ = 1;
-                                break;
-                	}
-
-			/* exit if the interrupt is for another CPU on the */
-			/* same IRQ */
-			if(!card_found_for_IRQ)
-				return IRQ_HANDLED;
-
-       	 		if (!card || 
-			   (card->wandev.state == WAN_UNCONFIGURED && !card->configured)){
-					printk(KERN_INFO
-						"Received IRQ %d for CPU #%c\n",
-						irq, CPU_no);
-					printk(KERN_INFO
-						"IRQ for unconfigured adapter\n");
-					S514_intack(&card->hw, int_status);
-					return IRQ_HANDLED;
-       			}
-
-	        	if (card->in_isr) {
-        	       		printk(KERN_INFO
-					"%s: interrupt re-entrancy on IRQ %d\n",
-                       			card->devname, card->wandev.irq);
-				S514_intack(&card->hw, int_status);
- 				return IRQ_HANDLED;
-       			}
-
-			spin_lock(&card->wandev.lock);
-			if (card->next){
-				spin_lock(&card->next->wandev.lock);
-			}
-				
-	               	S514_intack(&card->hw, int_status);
-       			if (card->isr)
-				card->isr(card);
-
-			if (card->next){
-				spin_unlock(&card->next->wandev.lock);
-			}
-			spin_unlock(&card->wandev.lock);
-
-			/* handle a maximum of two interrupts (one for each */
-			/* CPU on the adapter) before returning */  
-			if((++ IRQ_count) == 2)
-				return IRQ_HANDLED;
-		}
-	}
-
-	else {			/* handle interrupt on S508 adapter */
-
-		if (!card || ((card->wandev.state == WAN_UNCONFIGURED) && !card->configured))
-			return IRQ_HANDLED;
-
-		if (card->in_isr) {
-			printk(KERN_INFO
-				"%s: interrupt re-entrancy on IRQ %d!\n",
-				card->devname, card->wandev.irq);
-			return IRQ_HANDLED;
-		}
-
-		spin_lock(&card->wandev.lock);
-		if (card->next){
-			spin_lock(&card->next->wandev.lock);
-		}
-	
-		sdla_intack(&card->hw);
-		if (card->isr)
-			card->isr(card);
-		
-		if (card->next){
-			spin_unlock(&card->next->wandev.lock);
-		}
-		spin_unlock(&card->wandev.lock);
-
-	}
-        return IRQ_HANDLED;
-#undef	card
-}
-
-/*============================================================================
- * This routine is called by the protocol-specific modules when network
- * interface is being open.  The only reason we need this, is because we
- * have to call MOD_INC_USE_COUNT, but cannot include 'module.h' where it's
- * defined more than once into the same kernel module.
- */
-void wanpipe_open (sdla_t* card)
-{
-	++card->open_cnt;
-}
-
-/*============================================================================
- * This routine is called by the protocol-specific modules when network
- * interface is being closed.  The only reason we need this, is because we
- * have to call MOD_DEC_USE_COUNT, but cannot include 'module.h' where it's
- * defined more than once into the same kernel module.
- */
-void wanpipe_close (sdla_t* card)
-{
-	--card->open_cnt;
-}
-
-/*============================================================================
- * Set WAN device state.
- */
-void wanpipe_set_state (sdla_t* card, int state)
-{
-	if (card->wandev.state != state) {
-		switch (state) {
-		case WAN_CONNECTED:
-			printk (KERN_INFO "%s: link connected!\n",
-				card->devname);
-			break;
-
-		case WAN_CONNECTING:
-			printk (KERN_INFO "%s: link connecting...\n",
-				card->devname);
-			break;
-
-		case WAN_DISCONNECTED:
-			printk (KERN_INFO "%s: link disconnected!\n",
-				card->devname);
-			break;
-		}
-		card->wandev.state = state;
-	}
-	card->state_tick = jiffies;
-}
-
-sdla_t * wanpipe_find_card (char *name)
-{
-	int cnt;
-	for (cnt = 0; cnt < ncards; ++ cnt) {
-		sdla_t* card = &card_array[cnt];
-		if (!strcmp(card->devname,name))
-			return card;
-	}
-	return NULL;
-}
-
-sdla_t * wanpipe_find_card_num (int num)
-{
-	if (num < 1 || num > ncards)
-		return NULL;	
-	num--;
-	return &card_array[num];
-}
-
-/*
- * @work_pointer:	work_struct to be done;
- * 			should already have PREPARE_WORK() or
- * 			  INIT_WORK() done on it by caller;
- */
-void wanpipe_queue_work (struct work_struct *work_pointer)
-{
-	if (test_and_set_bit(1, (void*)&wanpipe_bh_critical))
-		printk(KERN_INFO "CRITICAL IN QUEUING WORK\n");
-
-	queue_work(wanpipe_wq, work_pointer);
-	clear_bit(1,(void*)&wanpipe_bh_critical);
-}
-
-void wakeup_sk_bh(struct net_device *dev)
-{
-	wanpipe_common_t *chan = dev->priv;
-
-	if (test_bit(0,&chan->common_critical))
-		return;
-	
-	if (chan->sk && chan->tx_timer){
-		chan->tx_timer->expires=jiffies+1;
-		add_timer(chan->tx_timer);
-	}
-}
-
-int change_dev_flags(struct net_device *dev, unsigned flags)
-{
-	struct ifreq if_info;
-	mm_segment_t fs = get_fs();
-	int err;
-
-	memset(&if_info, 0, sizeof(if_info));
-	strcpy(if_info.ifr_name, dev->name);
-	if_info.ifr_flags = flags;	
-
-	set_fs(get_ds());     /* get user space block */ 
-	err = devinet_ioctl(SIOCSIFFLAGS, &if_info);
-	set_fs(fs);
-
-	return err;
-}
-
-unsigned long get_ip_address(struct net_device *dev, int option)
-{
-	
-	struct in_ifaddr *ifaddr;
-	struct in_device *in_dev;
-	unsigned long addr = 0;
-
-	rcu_read_lock();
-	if ((in_dev = __in_dev_get_rcu(dev)) == NULL){
-		goto out;
-	}
-
-	if ((ifaddr = in_dev->ifa_list)== NULL ){
-		goto out;
-	}
-	
-	switch (option){
-
-	case WAN_LOCAL_IP:
-		addr = ifaddr->ifa_local;
-		break;
-	
-	case WAN_POINTOPOINT_IP:
-		addr = ifaddr->ifa_address;
-		break;	
-
-	case WAN_NETMASK_IP:
-		addr = ifaddr->ifa_mask;
-		break;
-
-	case WAN_BROADCAST_IP:
-		addr = ifaddr->ifa_broadcast;
-		break;
-	default:
-		break;
-	}
-
-out:
-	rcu_read_unlock();
-	return addr;
-}	
-
-void add_gateway(sdla_t *card, struct net_device *dev)
-{
-	mm_segment_t oldfs;
-	struct rtentry route;
-	int res;
-
-	memset((char*)&route,0,sizeof(struct rtentry));
-
-	((struct sockaddr_in *)
-		&(route.rt_dst))->sin_addr.s_addr = 0;
-	((struct sockaddr_in *)
-		&(route.rt_dst))->sin_family = AF_INET;
-
-	((struct sockaddr_in *)
-		&(route.rt_genmask))->sin_addr.s_addr = 0;
-	((struct sockaddr_in *) 
-		&(route.rt_genmask)) ->sin_family = AF_INET;
-
-
-	route.rt_flags = 0;  
-	route.rt_dev = dev->name;
-
-	oldfs = get_fs();
-	set_fs(get_ds());
-	res = ip_rt_ioctl(SIOCADDRT,&route);
-	set_fs(oldfs);
-
-	if (res == 0){
-		printk(KERN_INFO "%s: Gateway added for %s\n",
-			card->devname,dev->name);
-	}
-
-	return;
-}
-
-MODULE_LICENSE("GPL");
-
-/****** End *********************************************************/
diff --git a/drivers/net/wan/wanpipe_multppp.c b/drivers/net/wan/wanpipe_multppp.c
deleted file mode 100644
index 812a118..0000000
--- a/drivers/net/wan/wanpipe_multppp.c
+++ /dev/null
@@ -1,2358 +0,0 @@
-/*****************************************************************************
-* wanpipe_multppp.c Multi-Port PPP driver module.
-*
-* Authors: 	Nenad Corbic <ncorbic@sangoma.com>
-*
-* Copyright:	(c) 1995-2001 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.
-* ============================================================================
-* Dec 15 2000   Updated for 2.4.X kernel
-* Nov 15 2000   Fixed the SyncPPP support for kernels 2.2.16 and higher.
-*   		The pppstruct has changed.
-* Jul 13 2000	Using the kernel Syncppp module on top of RAW Wanpipe CHDLC
-*  		module.
-*****************************************************************************/
-
-#include <linux/module.h>
-#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/slab.h>	/* kmalloc(), kfree() */
-#include <linux/wanrouter.h>	/* WAN router definitions */
-#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
-#include <linux/if_arp.h>	/* ARPHRD_* defines */
-#include <linux/jiffies.h>	/* time_after() macro */
-
-#include <linux/in.h>		/* sockaddr_in */
-#include <linux/inet.h>	
-#include <linux/if.h>
-#include <asm/byteorder.h>	/* htons(), etc. */
-#include <linux/sdlapci.h>
-#include <asm/io.h>
-
-#include <linux/sdla_chdlc.h>		/* CHDLC firmware API definitions */
-#include <linux/sdla_asy.h>           	/* CHDLC (async) API definitions */
-
-#include <linux/if_wanpipe_common.h>    /* Socket Driver common area */
-#include <linux/if_wanpipe.h>		
-
-
-#include <linux/inetdevice.h>
-#include <asm/uaccess.h>
-
-#include <net/syncppp.h>
-
-
-/****** Defines & Macros ****************************************************/
-
-#ifdef	_DEBUG_
-#define	STATIC
-#else
-#define	STATIC		static
-#endif
-
-/* reasons for enabling the timer interrupt on the adapter */
-#define TMR_INT_ENABLED_UDP   	0x01
-#define TMR_INT_ENABLED_UPDATE	0x02
-#define TMR_INT_ENABLED_CONFIG  0x04
- 
-#define	CHDLC_DFLT_DATA_LEN	1500		/* default MTU */
-#define CHDLC_HDR_LEN		1
-
-#define IFF_POINTTOPOINT 0x10
-
-#define CHDLC_API 0x01
-
-#define PORT(x)   (x == 0 ? "PRIMARY" : "SECONDARY" )
-#define MAX_BH_BUFF	10
-
-#define CRC_LENGTH 	2 
-#define PPP_HEADER_LEN 	4
- 
-/******Data Structures*****************************************************/
-
-/* This structure is placed in the private data area of the device structure.
- * The card structure used to occupy the private area but now the following 
- * structure will incorporate the card structure along with CHDLC specific data
- */
-
-typedef struct chdlc_private_area
-{
-	void *if_ptr;				/* General Pointer used by SPPP */
-	wanpipe_common_t common;
-	sdla_t		*card;
-	int 		TracingEnabled;		/* For enabling Tracing */
-	unsigned long 	curr_trace_addr;	/* Used for Tracing */
-	unsigned long 	start_trace_addr;
-	unsigned long 	end_trace_addr;
-	unsigned long 	base_addr_trace_buffer;
-	unsigned long 	end_addr_trace_buffer;
-	unsigned short 	number_trace_elements;
-	unsigned  	available_buffer_space;
-	unsigned long 	router_start_time;
-	unsigned char 	route_status;
-	unsigned char 	route_removed;
-	unsigned long 	tick_counter;		/* For 5s timeout counter */
-	unsigned long 	router_up_time;
-        u32             IP_address;		/* IP addressing */
-        u32             IP_netmask;
-	unsigned char  mc;			/* Mulitcast support on/off */
-	unsigned short udp_pkt_lgth;		/* udp packet processing */
-	char udp_pkt_src;
-	char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
-	unsigned short timer_int_enabled;
-	char update_comms_stats;		/* updating comms stats */
-
-	//FIXME: add driver stats as per frame relay!
-
-} chdlc_private_area_t;
-
-/* Route Status options */
-#define NO_ROUTE	0x00
-#define ADD_ROUTE	0x01
-#define ROUTE_ADDED	0x02
-#define REMOVE_ROUTE	0x03
-
-
-/* variable for keeping track of enabling/disabling FT1 monitor status */
-static int rCount = 0;
-
-/* variable for tracking how many interfaces to open for WANPIPE on the
-   two ports */
-
-extern void disable_irq(unsigned int);
-extern void enable_irq(unsigned int);
-
-/****** Function Prototypes *************************************************/
-/* WAN link driver entry points. These are called by the WAN router module. */
-static int update(struct wan_device* wandev);
-static int new_if(struct wan_device* wandev, struct net_device* dev,
-		  wanif_conf_t* conf);
-static int del_if(struct wan_device* wandev, struct net_device* dev);
-
-/* Network device interface */
-static int if_init(struct net_device* dev);
-static int if_open(struct net_device* dev);
-static int if_close(struct net_device* dev);
-static int if_send(struct sk_buff* skb, struct net_device* dev);
-static struct net_device_stats* if_stats(struct net_device* dev);
-
-static void if_tx_timeout(struct net_device *dev);
-
-/* CHDLC Firmware interface functions */
-static int chdlc_configure 	(sdla_t* card, void* data);
-static int chdlc_comm_enable 	(sdla_t* card);
-static int chdlc_comm_disable 	(sdla_t* card);
-static int chdlc_read_version 	(sdla_t* card, char* str);
-static int chdlc_set_intr_mode 	(sdla_t* card, unsigned mode);
-static int chdlc_send (sdla_t* card, void* data, unsigned len);
-static int chdlc_read_comm_err_stats (sdla_t* card);
-static int chdlc_read_op_stats (sdla_t* card);
-static int config_chdlc (sdla_t *card);
-
-
-/* Miscellaneous CHDLC Functions */
-static int set_chdlc_config (sdla_t* card);
-static void init_chdlc_tx_rx_buff(sdla_t* card, struct net_device *dev);
-static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
-static int process_chdlc_exception(sdla_t *card);
-static int process_global_exception(sdla_t *card);
-static int update_comms_stats(sdla_t* card,
-        chdlc_private_area_t* chdlc_priv_area);
-static void port_set_state (sdla_t *card, int);
-
-/* Interrupt handlers */
-static void wsppp_isr (sdla_t* card);
-static void rx_intr (sdla_t* card);
-static void timer_intr(sdla_t *);
-
-/* Miscellaneous functions */
-static int reply_udp( unsigned char *data, unsigned int mbox_len );
-static int intr_test( sdla_t* card);
-static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
-static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
-			      struct sk_buff *skb, struct net_device* dev,
-			      chdlc_private_area_t* chdlc_priv_area);
-static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,  
-				chdlc_private_area_t* chdlc_priv_area);
-static unsigned short calc_checksum (char *, int);
-static void s508_lock (sdla_t *card, unsigned long *smp_flags);
-static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
-static void send_ppp_term_request(struct net_device *dev);
-
-
-static int  Intr_test_counter;
-/****** Public Functions ****************************************************/
-
-/*============================================================================
- * Cisco HDLC protocol initialization routine.
- *
- * This routine is called by the main WANPIPE module during setup.  At this
- * point adapter is completely initialized and 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 wsppp_init (sdla_t* card, wandev_conf_t* conf)
-{
-	unsigned char port_num;
-	int err;
-	unsigned long max_permitted_baud = 0;
-	SHARED_MEMORY_INFO_STRUCT *flags;
-
-	union
-		{
-		char str[80];
-		} u;
-	volatile CHDLC_MAILBOX_STRUCT* mb;
-	CHDLC_MAILBOX_STRUCT* mb1;
-	unsigned long timeout;
-
-	/* Verify configuration ID */
-	if (conf->config_id != WANCONFIG_MPPP) {
-		printk(KERN_INFO "%s: invalid configuration ID %u!\n",
-				  card->devname, conf->config_id);
-		return -EINVAL;
-	}
-
-	/* Find out which Port to use */
-	if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
-		if (card->next){
-
-			if (conf->comm_port != card->next->u.c.comm_port){
-				card->u.c.comm_port = conf->comm_port;
-			}else{
-				printk(KERN_ERR "%s: ERROR - %s port used!\n",
-        		        	card->wandev.name, PORT(conf->comm_port));
-				return -EINVAL;
-			}
-		}else{
-			card->u.c.comm_port = conf->comm_port;
-		}
-	}else{
-		printk(KERN_ERR "%s: ERROR - Invalid Port Selected!\n",
-                			card->wandev.name);
-		return -EINVAL;
-	}
-	
-
-	/* Initialize protocol-specific fields */
-	if(card->hw.type != SDLA_S514){
-
-		if (card->u.c.comm_port == WANOPT_PRI){	
-			card->mbox  = (void *) card->hw.dpmbase;
-		}else{
-			card->mbox  = (void *) card->hw.dpmbase + 
-				SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
-		}	
-	}else{ 
-		/* for a S514 adapter, set a pointer to the actual mailbox in the */
-		/* allocated virtual memory area */
-		if (card->u.c.comm_port == WANOPT_PRI){
-			card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
-		}else{
-			card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
-		}	
-	}
-
-	mb = mb1 = card->mbox;
-
-	if (!card->configured){
-
-		/* The board will place an 'I' in the return code to indicate that it is
-	   	ready to accept commands.  We expect this to be completed in less
-           	than 1 second. */
-
-		timeout = jiffies + 1 * HZ;
-		while (mb->return_code != 'I')	/* Wait 1s for board to initialize */
-			if (time_after(jiffies, timeout)) break;
-
-		if (mb->return_code != 'I') {
-			printk(KERN_INFO
-				"%s: Initialization not completed by adapter\n",
-				card->devname);
-			printk(KERN_INFO "Please contact Sangoma representative.\n");
-			return -EIO;
-		}
-	}
-
-	/* 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 (chdlc_read_version(card, u.str))
-		return -EIO;
-
-	printk(KERN_INFO "%s: Running Raw CHDLC firmware v%s\n" 
-			 "%s: for Multi-Port PPP protocol.\n",
-			card->devname,u.str,card->devname); 
-
-	card->isr			= &wsppp_isr;
-	card->poll			= NULL;
-	card->exec			= NULL;
-	card->wandev.update		= &update;
- 	card->wandev.new_if		= &new_if;
-	card->wandev.del_if		= &del_if;
-	card->wandev.udp_port   	= conf->udp_port;
-
-	card->wandev.new_if_cnt = 0;
-
-	/* reset the number of times the 'update()' proc has been called */
-	card->u.c.update_call_count = 0;
-	
-	card->wandev.ttl = conf->ttl;
-	card->wandev.interface = conf->interface; 
-
-	if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
-	    card->hw.type != SDLA_S514){
-		printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n",
-			card->devname, PORT(card->u.c.comm_port));
-		return -EIO;
-	}
-
-
-	card->wandev.clocking = conf->clocking;
-
-	port_num = card->u.c.comm_port;
-
-	/* Setup Port Bps */
-
-	if(card->wandev.clocking) {
-		if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
-			/* For Primary Port 0 */
-               		max_permitted_baud =
-				(card->hw.type == SDLA_S514) ?
-				PRI_MAX_BAUD_RATE_S514 : 
-				PRI_MAX_BAUD_RATE_S508;
-		}
-		else if(port_num == WANOPT_SEC) {
-			/* For Secondary Port 1 */
-                        max_permitted_baud =
-                               (card->hw.type == SDLA_S514) ?
-                                SEC_MAX_BAUD_RATE_S514 :
-                                SEC_MAX_BAUD_RATE_S508;
-                        }
-  
-			if(conf->bps > max_permitted_baud) {
-				conf->bps = max_permitted_baud;
-				printk(KERN_INFO "%s: Baud too high!\n",
-					card->wandev.name);
- 				printk(KERN_INFO "%s: Baud rate set to %lu bps\n", 
-					card->wandev.name, max_permitted_baud);
-			}
-                             
-			card->wandev.bps = conf->bps;
-	}else{
-        	card->wandev.bps = 0;
-  	}
-
-	/* Setup the Port MTU */
-	if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
-
-		/* For Primary Port 0 */
-		card->wandev.mtu =
-			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
-			min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
-			CHDLC_DFLT_DATA_LEN;
-	} else if(port_num == WANOPT_SEC) { 
-		/* For Secondary Port 1 */
-		card->wandev.mtu =
-			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
-			min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
-			CHDLC_DFLT_DATA_LEN;
-	}
-
-	/* Add on a PPP Header */
-	card->wandev.mtu += PPP_HEADER_LEN;
-
-	/* Set up the interrupt status area */
-	/* Read the CHDLC Configuration and obtain: 
-	 *	Ptr to shared memory infor struct
-         * Use this pointer to calculate the value of card->u.c.flags !
- 	 */
-	mb1->buffer_length = 0;
-	mb1->command = READ_CHDLC_CONFIGURATION;
-	err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
-	if(err != COMMAND_OK) {
-		clear_bit(1, (void*)&card->wandev.critical);
-
-                if(card->hw.type != SDLA_S514)
-                	enable_irq(card->hw.irq);
-
-		chdlc_error(card, err, mb1);
-		return -EIO;
-	}
-
-	if(card->hw.type == SDLA_S514){
-               	card->u.c.flags = (void *)(card->hw.dpmbase +
-               		(((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
-			ptr_shared_mem_info_struct));
-        }else{
-                card->u.c.flags = (void *)(card->hw.dpmbase +
-                        (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
-			ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
-	}
-	
-	flags = card->u.c.flags;
-	
-	/* This is for the ports link state */
-	card->wandev.state = WAN_DUALPORT;
-	card->u.c.state = WAN_DISCONNECTED;
-
-
-	if (!card->wandev.piggyback){
-		err = intr_test(card);
-
-		if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { 
-			printk(KERN_ERR "%s: Interrupt test failed (%i)\n",
-					card->devname, Intr_test_counter);
-			printk(KERN_ERR "%s: Please choose another interrupt\n",
-					card->devname);
-			return  -EIO;
-		}
-			
-		printk(KERN_INFO "%s: Interrupt test passed (%i)\n", 
-				card->devname, Intr_test_counter);
-	}
-
-
-	if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
-		printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
-				card->devname);
-		return -EIO;	
-        }
-	
-	/* Mask the Timer interrupt */
-	flags->interrupt_info_struct.interrupt_permission &= 
-		~APP_INT_ON_TIMER;
-
-	printk(KERN_INFO "\n");
-
-	return 0;
-}
-
-/******* WAN Device Driver Entry Points *************************************/
-
-/*============================================================================
- * Update device status & statistics
- * This procedure is called when updating the PROC file system and returns
- * various communications statistics. These statistics are accumulated from 3 
- * different locations:
- * 	1) The 'if_stats' recorded for the device.
- * 	2) Communication error statistics on the adapter.
- *      3) CHDLC operational statistics on the adapter.
- * The board level statistics are read during a timer interrupt. Note that we 
- * read the error and operational statistics during consecitive timer ticks so
- * as to minimize the time that we are inside the interrupt handler.
- *
- */
-static int update(struct wan_device* wandev)
-{
-	sdla_t* card = wandev->private;
- 	struct net_device* dev;
-        volatile chdlc_private_area_t* chdlc_priv_area;
-        SHARED_MEMORY_INFO_STRUCT *flags;
-	unsigned long timeout;
-
-	/* sanity checks */
-	if((wandev == NULL) || (wandev->private == NULL))
-		return -EFAULT;
-	
-	if(wandev->state == WAN_UNCONFIGURED)
-		return -ENODEV;
-
-	/* more sanity checks */
-        if(!card->u.c.flags)
-                return -ENODEV;
-
-	if((dev=card->wandev.dev) == NULL)
-		return -ENODEV;
-
-	if((chdlc_priv_area=dev->priv) == NULL)
-		return -ENODEV;
-
-      	flags = card->u.c.flags;
-
-       	if(chdlc_priv_area->update_comms_stats){
-		return -EAGAIN;
-	}
-			
-	/* we will need 2 timer interrupts to complete the */
-	/* reading of the statistics */
-	chdlc_priv_area->update_comms_stats = 2;
-       	flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
-	chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
-  
-	/* wait a maximum of 1 second for the statistics to be updated */ 
-        timeout = jiffies + 1 * HZ;
-        for(;;) {
-		if(chdlc_priv_area->update_comms_stats == 0)
-			break;
-                if (time_after(jiffies, timeout)){
-    			chdlc_priv_area->update_comms_stats = 0;
- 			chdlc_priv_area->timer_int_enabled &=
-				~TMR_INT_ENABLED_UPDATE; 
- 			return -EAGAIN;
-		}
-        }
-
-	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(struct wan_device* wandev, struct net_device* pdev,
-		  wanif_conf_t* conf)
-{
-
-	struct ppp_device *pppdev = (struct ppp_device *)pdev;
-	struct net_device *dev = NULL;
-	struct sppp *sp;
-	sdla_t* card = wandev->private;
-	chdlc_private_area_t* chdlc_priv_area;
-	
-	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 */
-	chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
-	
-	if(chdlc_priv_area == NULL) 
-		return -ENOMEM;
-
-	memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
-
-	chdlc_priv_area->card = card; 
-
-	/* initialize data */
-	strcpy(card->u.c.if_name, conf->name);
-
-	if(card->wandev.new_if_cnt > 0) {
-                kfree(chdlc_priv_area);
-		return -EEXIST;
-	}
-
-	card->wandev.new_if_cnt++;
-
-	chdlc_priv_area->TracingEnabled = 0;
-
-	//We don't need this any more
-	chdlc_priv_area->route_status = NO_ROUTE;
-	chdlc_priv_area->route_removed = 0;
-
-	printk(KERN_INFO "%s: Firmware running in HDLC STREAMING Mode\n",
-		wandev->name);
-	
-	/* Setup wanpipe as a router (WANPIPE) or as an API */
-	if( strcmp(conf->usedby, "WANPIPE") == 0) {
-		printk(KERN_INFO "%s: Driver running in WANPIPE mode!\n",
-			wandev->name);
-		card->u.c.usedby = WANPIPE;
-	} else {
-		printk(KERN_INFO 
-			"%s: API Mode is not supported for SyncPPP!\n",
-			wandev->name);
-		kfree(chdlc_priv_area);
-		return -EINVAL;
-	}
-
-	/* Get Multicast Information */
-	chdlc_priv_area->mc = conf->mc;
-
-
-	chdlc_priv_area->if_ptr = pppdev;
-
-	/* prepare network device data space for registration */
-
-	strcpy(dev->name,card->u.c.if_name);
-
-	/* Attach PPP protocol layer to pppdev
-	 * The sppp_attach() will initilize the dev structure
-         * and setup ppp layer protocols.
-         * All we have to do is to bind in:
-         *        if_open(), if_close(), if_send() and get_stats() functions.
-         */
-	sppp_attach(pppdev);
-	dev = pppdev->dev;
-	sp = &pppdev->sppp;
-	
-	/* Enable PPP Debugging */
-	// FIXME Fix this up somehow
-	//sp->pp_flags |= PP_DEBUG; 	
-	sp->pp_flags &= ~PP_CISCO;
-
-	dev->init = &if_init;
-	dev->priv = chdlc_priv_area;
-	
-	return 0;
-}
-
-
-
-
-/*============================================================================
- * Delete logical channel.
- */
-static int del_if(struct wan_device* wandev, struct net_device* dev)
-{
-	chdlc_private_area_t *chdlc_priv_area = dev->priv;
-	sdla_t *card = chdlc_priv_area->card;
-	unsigned long smp_lock;
-	
-	/* Detach the PPP layer */
-	printk(KERN_INFO "%s: Detaching SyncPPP Module from %s\n",
-			wandev->name,dev->name);
-
-	lock_adapter_irq(&wandev->lock,&smp_lock);
-
-	sppp_detach(dev);
-	chdlc_priv_area->if_ptr=NULL;
-	
-	chdlc_set_intr_mode(card, 0);
-	if (card->u.c.comm_enabled)
-		chdlc_comm_disable(card);
-	unlock_adapter_irq(&wandev->lock,&smp_lock);
-	
-	port_set_state(card, WAN_DISCONNECTED);
-
-	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)
-{
-	chdlc_private_area_t* chdlc_priv_area = dev->priv;
-	sdla_t* card = chdlc_priv_area->card;
-	struct wan_device* wandev = &card->wandev;
-	
-	/* NOTE: Most of the dev initialization was
-         *       done in sppp_attach(), called by new_if() 
-         *       function. All we have to do here is
-         *       to link four major routines below. 
-         */
-
-	/* Initialize device driver entry points */
-	dev->open		= &if_open;
-	dev->stop		= &if_close;
-	dev->hard_start_xmit	= &if_send;
-	dev->get_stats		= &if_stats;
-	dev->tx_timeout		= &if_tx_timeout;
-	dev->watchdog_timeo	= TX_TIMEOUT;
-
-
-	/* Initialize hardware parameters */
-	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 transmit buffer queue length 
-         * If we over fill this queue the packets will
-         * be droped by the kernel.
-         * sppp_attach() sets this to 10, but
-         * 100 will give us more room at low speeds.
-	 */
-        dev->tx_queue_len = 100;
-   
-	return 0;
-}
-
-
-/*============================================================================
- * Handle transmit timeout event from netif watchdog
- */
-static void if_tx_timeout(struct net_device *dev)
-{
-    	chdlc_private_area_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.
-	 */
-
-	++card->wandev.stats.collisions;
-
-	printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
-	netif_wake_queue (dev);
-}
-
-
-/*============================================================================
- * Open network interface.
- * o 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)
-{
-	chdlc_private_area_t* chdlc_priv_area = dev->priv;
-	sdla_t* card = chdlc_priv_area->card;
-	struct timeval tv;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-
-	/* Only one open per interface is allowed */
-	if (netif_running(dev))
-		return -EBUSY;
-
-	/* Start PPP Layer */
-	if (sppp_open(dev)){
-		return -EIO;
-	}
-
-	do_gettimeofday(&tv);
-	chdlc_priv_area->router_start_time = tv.tv_sec;
- 
-	netif_start_queue(dev);
-	
-	wanpipe_open(card);
-
-	chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
-	flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
-	return 0;
-}
-
-/*============================================================================
- * Close network interface.
- * o if this is the last close, then disable communications and interrupts.
- * o reset flags.
- */
-static int if_close(struct net_device* dev)
-{
-	chdlc_private_area_t* chdlc_priv_area = dev->priv;
-	sdla_t* card = chdlc_priv_area->card;
-
-	/* Stop the PPP Layer */
-	sppp_close(dev);
-	netif_stop_queue(dev);
-
-	wanpipe_close(card);
-	
-	return 0;
-}
-
-/*============================================================================
- * 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 check link state. If link is not up, then drop the packet.
- * o execute adapter send command.
- * o free socket buffer
- *
- * Return:	0	complete (socket buffer must be freed)
- *		non-0	packet may be re-transmitted (tbusy must be set)
- *
- * Notes:
- * 1. This routine is called either by the protocol stack or by the "net
- *    bottom half" (with interrupts enabled).
- * 2. Setting tbusy flag will inhibit further transmit requests from the
- *    protocol stack and can be used for flow control with protocol layer.
- */
-static int if_send(struct sk_buff* skb, struct net_device* dev)
-{
-	chdlc_private_area_t *chdlc_priv_area = dev->priv;
-	sdla_t *card = chdlc_priv_area->card;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-	INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
-	int udp_type = 0;
-	unsigned long smp_flags;
-	int err=0;
-
-	netif_stop_queue(dev);
-
-	
-	if (skb == NULL){
-		/* If we get here, some higher layer thinks we've missed an
-		 * tx-done interrupt.
-		 */
-		printk(KERN_INFO "%s: Received NULL skb buffer! interface %s got kicked!\n",
-			card->devname, dev->name);
-
-		netif_wake_queue(dev);
-		return 0;
-	}
-
-   	if (ntohs(skb->protocol) != htons(PVC_PROT)){
-		/* 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;
-			}
-			netif_start_queue(dev);
-			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(SEND_CRIT, (void*)&card->wandev.critical)){
-	
-		printk(KERN_INFO "%s: Critical in if_send: %lx\n",
-					card->wandev.name,card->wandev.critical);
-                ++card->wandev.stats.tx_dropped;
-		netif_start_queue(dev);
-		goto if_send_crit_exit;
-	}
-
-	if (card->wandev.state != WAN_CONNECTED){
-		++card->wandev.stats.tx_dropped;
-		netif_start_queue(dev);
-		goto if_send_crit_exit;
-	}
-	
-	if (chdlc_send(card, skb->data, skb->len)){
-		netif_stop_queue(dev);
-
-	}else{
-		++card->wandev.stats.tx_packets;
-       		card->wandev.stats.tx_bytes += skb->len;
-		dev->trans_start = jiffies;
-		netif_start_queue(dev);
-	}	
-
-if_send_crit_exit:
-	if (!(err=netif_queue_stopped(dev))){
-                dev_kfree_skb_any(skb);
-	}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;
-}
-
-
-/*============================================================================
- * 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.
- */
-static struct net_device_stats* if_stats(struct net_device* dev)
-{
-	sdla_t *my_card;
-	chdlc_private_area_t* chdlc_priv_area;
-
-	/* Shutdown bug fix. In del_if() we kill
-         * dev->priv pointer. This function, gets
-         * called after del_if(), thus check
-         * if pointer has been deleted */
-	if ((chdlc_priv_area=dev->priv) == NULL)
-		return NULL;
-
-	my_card = chdlc_priv_area->card;
-	return &my_card->wandev.stats; 
-}
-
-
-/****** 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);
-	else
-		card->u.c.comm_enabled=1;
-
-	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);
-
-	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)
-{
-	unsigned cmd = mb->command;
-
-	switch (err) {
-
-	case CMD_TIMEOUT:
-		printk(KERN_ERR "%s: command 0x%02X timed out!\n",
-			card->devname, cmd);
-		break;
-
-	case S514_BOTH_PORTS_SAME_CLK_MODE:
-		if(cmd == SET_CHDLC_CONFIGURATION) {
-			printk(KERN_INFO
-			 "%s: Configure both ports for the same clock source\n",
-				card->devname);
-			break;
-		}
-
-	default:
-		printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
-			card->devname, cmd, err);
-	}
-
-	return 0;
-}
-
-/****** Interrupt Handlers **************************************************/
-
-/*============================================================================
- * Cisco HDLC interrupt service routine.
- */
-STATIC void wsppp_isr (sdla_t* card)
-{
-	struct net_device* dev;
-	SHARED_MEMORY_INFO_STRUCT* flags = NULL;
-	int i;
-	sdla_t *my_card;
-
-
-	/* Check for which port the interrupt has been generated
-	 * Since Secondary Port is piggybacking on the Primary
-         * the check must be done here. 
-	 */
-
-	flags = card->u.c.flags;
-	if (!flags->interrupt_info_struct.interrupt_type){
-		/* Check for a second port (piggybacking) */
-		if((my_card = card->next)){
-			flags = my_card->u.c.flags;
-			if (flags->interrupt_info_struct.interrupt_type){
-				card = my_card;
-				card->isr(card);
-				return;
-			}
-		}
-	}
-
-	dev = card->wandev.dev;
-	card->in_isr = 1;
-	flags = card->u.c.flags;
-		
-	/* If we get an interrupt with no network device, stop the interrupts
-	 * and issue an error */
-	if ((!dev || !dev->priv) && flags->interrupt_info_struct.interrupt_type != 
-	    	COMMAND_COMPLETE_APP_INT_PEND){
-		goto isr_done;
-	}
-
-	
-	/* if critical due to peripheral operations
-	 * ie. update() or getstats() then reset the interrupt and
-	 * wait for the board to retrigger.
-	 */
-	if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
-		flags->interrupt_info_struct.
-					interrupt_type = 0;
-		goto isr_done;
-	}
-
-
-	/* On a 508 Card, if critical due to if_send 
-         * Major Error !!!
-	 */
-	if(card->hw.type != SDLA_S514) {
-		if(test_bit(0, (void*)&card->wandev.critical)) {
-			printk(KERN_INFO "%s: Critical while in ISR: %lx\n",
-				card->devname, card->wandev.critical);
-			goto isr_done;
-		}
-	}
-
-	switch(flags->interrupt_info_struct.interrupt_type) {
-
-		case RX_APP_INT_PEND:	/* 0x01: receive interrupt */
-			rx_intr(card);
-			break;
-
-		case TX_APP_INT_PEND:	/* 0x02: transmit interrupt */
-			flags->interrupt_info_struct.interrupt_permission &=
-				 ~APP_INT_ON_TX_FRAME;
-
-			netif_wake_queue(dev);
-			break;
-
-		case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
-			++ Intr_test_counter;
-			break;
-
-		case CHDLC_EXCEP_COND_APP_INT_PEND:	/* 0x20 */
-			process_chdlc_exception(card);
-			break;
-
-		case GLOBAL_EXCEP_COND_APP_INT_PEND:
-			process_global_exception(card);
-			break;
-
-		case TIMER_APP_INT_PEND:
-			timer_intr(card);
-			break;
-
-		default:
-			printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", 
-				card->devname,
-				flags->interrupt_info_struct.interrupt_type);
-			printk(KERN_INFO "Code name: ");
-			for(i = 0; i < 4; i ++)
-				printk(KERN_INFO "%c",
-					flags->global_info_struct.codename[i]); 
-			printk(KERN_INFO "\nCode version: ");
-			for(i = 0; i < 4; i ++)
-				printk(KERN_INFO "%c", 
-					flags->global_info_struct.codeversion[i]); 
-			printk(KERN_INFO "\n");	
-			break;
-	}
-
-isr_done:
-	card->in_isr = 0;
-	flags->interrupt_info_struct.interrupt_type = 0;
-}
-
-/*============================================================================
- * Receive interrupt handler.
- */
-static void rx_intr (sdla_t* card)
-{
-	struct net_device *dev;
-	chdlc_private_area_t *chdlc_priv_area;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-	CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
-	struct sk_buff *skb;
-	unsigned len;
-	unsigned addr = rxbuf->ptr_data_bfr;
-	void *buf;
-	int i,udp_type;
-	
-	if (rxbuf->opp_flag != 0x01) {
-		printk(KERN_INFO 
-			"%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", 
-			card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
-                printk(KERN_INFO "Code name: ");
-                for(i = 0; i < 4; i ++)
-                        printk(KERN_INFO "%c",
-                                flags->global_info_struct.codename[i]);
-                printk(KERN_INFO "\nCode version: ");
-                for(i = 0; i < 4; i ++)
-                        printk(KERN_INFO "%c",
-                                flags->global_info_struct.codeversion[i]);
-                printk(KERN_INFO "\n");
-
-
-		/* Bug Fix: Mar 6 2000
-                 * If we get a corrupted mailbox, it measn that driver 
-                 * is out of sync with the firmware. There is no recovery.
-                 * If we don't turn off all interrupts for this card
-                 * the machine will crash. 
-                 */
-		printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
-		printk(KERN_INFO "Please contact Sangoma Technologies !\n");
-		chdlc_set_intr_mode(card,0);	
-		return;
-	}
-
-	dev = card->wandev.dev;
-
-	if (!dev){ 
-		goto rx_exit;
-	}
-	
-	if (!netif_running(dev)){
-		goto rx_exit;
-	}
-
-	chdlc_priv_area = dev->priv;
-
-	if (rxbuf->error_flag){	
-		goto rx_exit;
-	}
-	/* Take off two CRC bytes */
-
-	if (rxbuf->frame_length < 7 || rxbuf->frame_length > 1506 ){
-		goto rx_exit;
-	}	
-
-	len = rxbuf->frame_length - CRC_LENGTH;
-
-	/* Allocate socket buffer */
-	skb = dev_alloc_skb(len);
-
-	if (skb == NULL) {
-		if (net_ratelimit()){
-			printk(KERN_INFO "%s: no socket buffers available!\n",
-						card->devname);
-		}
-		++card->wandev.stats.rx_dropped;
-		goto rx_exit;
-	}
-
-	/* Copy data to the socket buffer */
-	if((addr + len) > card->u.c.rx_top + 1) {
-		unsigned tmp = card->u.c.rx_top - addr + 1;
-		buf = skb_put(skb, tmp);
-		sdla_peek(&card->hw, addr, buf, tmp);
-		addr = card->u.c.rx_base;
-		len -= tmp;
-	}
-		
-	buf = skb_put(skb, len);
-	sdla_peek(&card->hw, addr, buf, len);
-
-	skb->protocol = htons(ETH_P_WAN_PPP);
-
-	card->wandev.stats.rx_packets ++;
-	card->wandev.stats.rx_bytes += skb->len;
-	udp_type = udp_pkt_type( skb, card );
-
-	if(udp_type == UDP_CPIPE_TYPE) {
-		if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
-   				      card, skb, dev, chdlc_priv_area)) {
-     		        flags->interrupt_info_struct.
-						interrupt_permission |= 
-							APP_INT_ON_TIMER; 
-		}
-	}else{
-               	/* Pass it up the protocol stack */
-                skb->dev = dev;
-                skb->mac.raw  = skb->data;
-                netif_rx(skb);
-                dev->last_rx = jiffies;
-	}
-
-rx_exit:
-	/* Release buffer element and calculate a pointer to the next one */
-	rxbuf->opp_flag = 0x00;
-	card->u.c.rxmb = ++ rxbuf;
-	if((void*)rxbuf > card->u.c.rxbuf_last){
-		card->u.c.rxmb = card->u.c.rxbuf_base;
-	}
-}
-
-/*============================================================================
- * Timer interrupt handler.
- * The timer interrupt is used for two purposes:
- *    1) Processing udp calls from 'cpipemon'.
- *    2) Reading board-level statistics for updating the proc file system.
- */
-void timer_intr(sdla_t *card)
-{
-        struct net_device* dev;
-        chdlc_private_area_t* chdlc_priv_area = NULL;
-        SHARED_MEMORY_INFO_STRUCT* flags = NULL;
-
-        dev = card->wandev.dev; 
-        chdlc_priv_area = dev->priv;
-
-	if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) {
-		if (!config_chdlc(card)){
-			chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
-		}
-	}
-	
-	/* process a udp call if pending */
-       	if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
-               	process_udp_mgmt_pkt(card, dev,
-                       chdlc_priv_area);
-		chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
-        }
-	
-
-	/* read the communications statistics if required */
-	if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
-		update_comms_stats(card, chdlc_priv_area);
-                if(!(-- chdlc_priv_area->update_comms_stats)) {
-			chdlc_priv_area->timer_int_enabled &= 
-				~TMR_INT_ENABLED_UPDATE;
-		}
-        }
-
-	/* only disable the timer interrupt if there are no udp or statistic */
-	/* updates pending */
-        if(!chdlc_priv_area->timer_int_enabled) {
-                flags = card->u.c.flags;
-                flags->interrupt_info_struct.interrupt_permission &=
-                        ~APP_INT_ON_TIMER;
-        }
-}
-
-/*------------------------------------------------------------------------------
-  Miscellaneous Functions
-	- set_chdlc_config() used to set configuration options on the board
-------------------------------------------------------------------------------*/
-
-static int set_chdlc_config(sdla_t* card)
-{
-
-	CHDLC_CONFIGURATION_STRUCT cfg;
-
-	memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
-
-	if(card->wandev.clocking)
-		cfg.baud_rate = card->wandev.bps;
-
-	cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
-		INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
-
-	cfg.modem_config_options	= 0;
-	//API OPTIONS
-	cfg.CHDLC_API_options		= DISCARD_RX_ERROR_FRAMES;
-	cfg.modem_status_timer		= 100;
-	cfg.CHDLC_protocol_options	= HDLC_STREAMING_MODE;
-	cfg.percent_data_buffer_for_Tx  = 50;
-	cfg.CHDLC_statistics_options	= (CHDLC_TX_DATA_BYTE_COUNT_STAT |
-		CHDLC_RX_DATA_BYTE_COUNT_STAT);
-	cfg.max_CHDLC_data_field_length	= card->wandev.mtu;
-
-	cfg.transmit_keepalive_timer	= 0;
-	cfg.receive_keepalive_timer	= 0;
-	cfg.keepalive_error_tolerance	= 0;
-	cfg.SLARP_request_timer		= 0;
-
-	cfg.IP_address		= 0;
-	cfg.IP_netmask		= 0;
-	
-	return chdlc_configure(card, &cfg);
-}
-
-/*============================================================================
- * Process global exception condition
- */
-static int process_global_exception(sdla_t *card)
-{
-	CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
-	int err;
-
-	mbox->buffer_length = 0;
-	mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
-	err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
-
-	if(err != CMD_TIMEOUT ){
-	
-		switch(mbox->return_code) {
-         
-	      	case EXCEP_MODEM_STATUS_CHANGE:
-
-			printk(KERN_INFO "%s: Modem status change\n",
-				card->devname);
-
-			switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
-				case (DCD_HIGH):
-					printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname);
-					break;
-				case (CTS_HIGH):
-                                        printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname);
-                                        break;
-                                case ((DCD_HIGH | CTS_HIGH)):
-                                        printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname);
-                                        break;
-				default:
-                                        printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname);
-                                        break;
-			}
-
-			if (!(mbox->data[0] & DCD_HIGH) || !(mbox->data[0] & DCD_HIGH)){
-				//printk(KERN_INFO "Sending TERM Request Manually !\n");
-				send_ppp_term_request(card->wandev.dev);
-			}	
-			break;
-
-                case EXCEP_TRC_DISABLED:
-                        printk(KERN_INFO "%s: Line trace disabled\n",
-				card->devname);
-                        break;
-
-		case EXCEP_IRQ_TIMEOUT:
-			printk(KERN_INFO "%s: IRQ timeout occurred\n",
-				card->devname); 
-			break;
-
-                default:
-                        printk(KERN_INFO "%s: Global exception %x\n",
-				card->devname, mbox->return_code);
-                        break;
-                }
-	}
-	return 0;
-}
-
-
-/*============================================================================
- * Process chdlc exception condition
- */
-static int process_chdlc_exception(sdla_t *card)
-{
-	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
-	int err;
-
-	mb->buffer_length = 0;
-	mb->command = READ_CHDLC_EXCEPTION_CONDITION;
-	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-	if(err != CMD_TIMEOUT) {
-	
-		switch (err) {
-
-		case EXCEP_LINK_ACTIVE:
-			port_set_state(card, WAN_CONNECTED);
-			break;
-
-		case EXCEP_LINK_INACTIVE_MODEM:
-			port_set_state(card, WAN_DISCONNECTED);
-			break;
-
-		case EXCEP_LOOPBACK_CONDITION:
-			printk(KERN_INFO "%s: Loopback Condition Detected.\n",
-						card->devname);
-			break;
-
-		case NO_CHDLC_EXCEP_COND_TO_REPORT:
-			printk(KERN_INFO "%s: No exceptions reported.\n",
-						card->devname);
-			break;
-		default:
-			printk(KERN_INFO "%s: Exception Condition %x!\n",
-					card->devname,err);
-			break;
-		}
-
-	}
-	return 0;
-}
-
-
-/*=============================================================================
- * Store a UDP management packet for later processing.
- */
-
-static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
-			      struct sk_buff *skb, struct net_device* dev,
-			      chdlc_private_area_t* chdlc_priv_area )
-{
-	int udp_pkt_stored = 0;
-
-	if(!chdlc_priv_area->udp_pkt_lgth &&
-	  (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
-        	chdlc_priv_area->udp_pkt_lgth = skb->len;
-		chdlc_priv_area->udp_pkt_src = udp_pkt_src;
-       		memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
-		chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
-		udp_pkt_stored = 1;
-	}
-
-	if(udp_pkt_src == UDP_PKT_FRM_STACK)
-		dev_kfree_skb_any(skb);
-	else
-                dev_kfree_skb_any(skb);
-	
-	return(udp_pkt_stored);
-}
-
-
-/*=============================================================================
- * Process UDP management packet.
- */
-
-static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
-				chdlc_private_area_t* chdlc_priv_area ) 
-{
-	unsigned char *buf;
-	unsigned int frames, len;
-	struct sk_buff *new_skb;
-	unsigned short buffer_length, real_len;
-	unsigned long data_ptr;
-	unsigned data_length;
-	int udp_mgmt_req_valid = 1;
-	CHDLC_MAILBOX_STRUCT *mb = card->mbox;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-	chdlc_udp_pkt_t *chdlc_udp_pkt;
-	struct timeval tv;
-	int err;
-	char ut_char;
-
-	chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
-
-	if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-
-		switch(chdlc_udp_pkt->cblock.command) {
-			case READ_GLOBAL_STATISTICS:
-			case READ_MODEM_STATUS:  
-			case READ_CHDLC_LINK_STATUS:
-			case CPIPE_ROUTER_UP_TIME:
-			case READ_COMMS_ERROR_STATS:
-			case READ_CHDLC_OPERATIONAL_STATS:
-
-			/* These two commands are executed for
-			 * each request */
-			case READ_CHDLC_CONFIGURATION:
-			case READ_CHDLC_CODE_VERSION:
-				udp_mgmt_req_valid = 1;
-				break;
-			default:
-				udp_mgmt_req_valid = 0;
-				break;
-		} 
-	}
-	
-  	if(!udp_mgmt_req_valid) {
-
-		/* set length to 0 */
-		chdlc_udp_pkt->cblock.buffer_length = 0;
-
-    		/* set return code */
-		chdlc_udp_pkt->cblock.return_code = 0xCD;
-
-		if (net_ratelimit()){	
-			printk(KERN_INFO 
-			"%s: Warning, Illegal UDP command attempted from network: %x\n",
-			card->devname,chdlc_udp_pkt->cblock.command);
-		}
-
-   	} else {
-	   	unsigned long trace_status_cfg_addr = 0;
-		TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
-		TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
-
-		switch(chdlc_udp_pkt->cblock.command) {
-
-		case CPIPE_ENABLE_TRACING:
-		     if (!chdlc_priv_area->TracingEnabled) {
-
-			/* OPERATE_DATALINE_MONITOR */
-
-			mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
-			mb->command = SET_TRACE_CONFIGURATION;
-
-    			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
-				trace_config = TRACE_ACTIVE;
-			/* Trace delay mode is not used because it slows
-			   down transfer and results in a standoff situation
-			   when there is a lot of data */
-
-			/* Configure the Trace based on user inputs */
-			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= 
-					chdlc_udp_pkt->data[0];
-
-			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
-			   trace_deactivation_timer = 4000;
-
-
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-			if (err != COMMAND_OK) {
-				chdlc_error(card,err,mb);
-				card->TracingEnabled = 0;
-				chdlc_udp_pkt->cblock.return_code = err;
-				mb->buffer_length = 0;
-				break;
-	    		} 
-
-			/* Get the base address of the trace element list */
-			mb->buffer_length = 0;
-			mb->command = READ_TRACE_CONFIGURATION;
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-
-			if (err != COMMAND_OK) {
-				chdlc_error(card,err,mb);
-				chdlc_priv_area->TracingEnabled = 0;
-				chdlc_udp_pkt->cblock.return_code = err;
-				mb->buffer_length = 0;
-				break;
-	    		} 	
-
-	   		trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
-				mb->data) -> ptr_trace_stat_el_cfg_struct;
-
-			sdla_peek(&card->hw, trace_status_cfg_addr,
-				 &trace_cfg_struct, sizeof(trace_cfg_struct));
-		    
-			chdlc_priv_area->start_trace_addr = trace_cfg_struct.
-				base_addr_trace_status_elements;
-
-			chdlc_priv_area->number_trace_elements = 
-					trace_cfg_struct.number_trace_status_elements;
-
-			chdlc_priv_area->end_trace_addr = (unsigned long)
-					((TRACE_STATUS_ELEMENT_STRUCT *)
-					 chdlc_priv_area->start_trace_addr + 
-					 (chdlc_priv_area->number_trace_elements - 1));
-
-			chdlc_priv_area->base_addr_trace_buffer = 
-					trace_cfg_struct.base_addr_trace_buffer;
-
-			chdlc_priv_area->end_addr_trace_buffer = 
-					trace_cfg_struct.end_addr_trace_buffer;
-
-		    	chdlc_priv_area->curr_trace_addr = 
-					trace_cfg_struct.next_trace_element_to_use;
-
-	    		chdlc_priv_area->available_buffer_space = 2000 - 
-								  sizeof(ip_pkt_t) -
-								  sizeof(udp_pkt_t) -
-							      	  sizeof(wp_mgmt_t) -
-								  sizeof(cblock_t) -
-							          sizeof(trace_info_t);	
-	       	     }
-		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
-		     mb->buffer_length = 0;
-	       	     chdlc_priv_area->TracingEnabled = 1;
-	       	     break;
-	   
-
-		case CPIPE_DISABLE_TRACING:
-		     if (chdlc_priv_area->TracingEnabled) {
-
-			/* OPERATE_DATALINE_MONITOR */
-			mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
-			mb->command = SET_TRACE_CONFIGURATION;
-    			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
-				trace_config = TRACE_INACTIVE;
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-		     }		
-
-		     chdlc_priv_area->TracingEnabled = 0;
-		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
-		     mb->buffer_length = 0;
-		     break;
-	   
-
-		case CPIPE_GET_TRACE_INFO:
-
-		     if (!chdlc_priv_area->TracingEnabled) {
-			chdlc_udp_pkt->cblock.return_code = 1;
-			mb->buffer_length = 0;
-			break;
-		     }
-
-  		     chdlc_udp_pkt->trace_info.ismoredata = 0x00;
-		     buffer_length = 0;	/* offset of packet already occupied */
-
-		     for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
-
-			trace_pkt_t *trace_pkt = (trace_pkt_t *)
-				&chdlc_udp_pkt->data[buffer_length];
-
-			sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
-			   	  (unsigned char *)&trace_element_struct,
-			   	  sizeof(TRACE_STATUS_ELEMENT_STRUCT));
-
-     			if (trace_element_struct.opp_flag == 0x00) {
-			 	break;
-			}
-
-			/* get pointer to real data */
-			data_ptr = trace_element_struct.ptr_data_bfr;
-
-			/* See if there is actual data on the trace buffer */
-			if (data_ptr){
-				data_length = trace_element_struct.trace_length;
-			}else{
-				data_length = 0;
-				chdlc_udp_pkt->trace_info.ismoredata = 0x01;
-			}
-	
-   			if( (chdlc_priv_area->available_buffer_space - buffer_length)
-				< ( sizeof(trace_pkt_t) + data_length) ) {
-
-                            /* indicate there are more frames on board & exit */
-				chdlc_udp_pkt->trace_info.ismoredata = 0x01;
-                               	break;
-                         }
-
-			trace_pkt->status = trace_element_struct.trace_type;
-
-			trace_pkt->time_stamp =
-				trace_element_struct.trace_time_stamp;
-
-			trace_pkt->real_length =
-				trace_element_struct.trace_length;
-
-			/* see if we can fit the frame into the user buffer */
-			real_len = trace_pkt->real_length;
-
-			if (data_ptr == 0) {
-			     	trace_pkt->data_avail = 0x00;
-			} else {
-				unsigned tmp = 0;
-
-				/* get the data from circular buffer
-				    must check for end of buffer */
-			        trace_pkt->data_avail = 0x01;
-
-				if ((data_ptr + real_len) >
-					     chdlc_priv_area->end_addr_trace_buffer + 1){
-
-				    	tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
-				    	sdla_peek(&card->hw, data_ptr,
-					       	  trace_pkt->data,tmp);
-				    	data_ptr = chdlc_priv_area->base_addr_trace_buffer;
-				}
-	
-		        	sdla_peek(&card->hw, data_ptr,
-					  &trace_pkt->data[tmp], real_len - tmp);
-			}	
-
-			/* zero the opp flag to show we got the frame */
-			ut_char = 0x00;
-			sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
-
-       			/* now move onto the next frame */
-       			chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
-
-       			/* check if we went over the last address */
-			if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
-				chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
-       			}
-
-            		if(trace_pkt->data_avail == 0x01) {
-				buffer_length += real_len - 1;
-			}
-	 
-	       	    	/* for the header */
-	            	buffer_length += sizeof(trace_pkt_t);
-
-		     }  /* For Loop */
-
-		     if (frames == chdlc_priv_area->number_trace_elements){
-			chdlc_udp_pkt->trace_info.ismoredata = 0x01;
-	             }
- 		     chdlc_udp_pkt->trace_info.num_frames = frames;
-		 
-    		     mb->buffer_length = buffer_length;
-		     chdlc_udp_pkt->cblock.buffer_length = buffer_length; 
-		 
-		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK; 
-		     
-		     break;
-
-
-		case CPIPE_FT1_READ_STATUS:
-			((unsigned char *)chdlc_udp_pkt->data )[0] =
-				flags->FT1_info_struct.parallel_port_A_input;
-
-			((unsigned char *)chdlc_udp_pkt->data )[1] =
-				flags->FT1_info_struct.parallel_port_B_input;
-				 
-			chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
-			mb->buffer_length = 2;
-			break;
-		
-		case CPIPE_ROUTER_UP_TIME:
-			do_gettimeofday( &tv );
-			chdlc_priv_area->router_up_time = tv.tv_sec - 
-					chdlc_priv_area->router_start_time;
-			*(unsigned long *)&chdlc_udp_pkt->data = 
-					chdlc_priv_area->router_up_time;	
-			mb->buffer_length = sizeof(unsigned long);
-			break;
-
-   		case FT1_MONITOR_STATUS_CTRL:
-			/* Enable FT1 MONITOR STATUS */
-	        	if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||  
-				(chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
-			
-			     	if( rCount++ != 0 ) {
-					chdlc_udp_pkt->cblock.
-					return_code = COMMAND_OK;
-					mb->buffer_length = 1;
-		  			break;
-		    	     	}
-	      		}
-
-	      		/* Disable FT1 MONITOR STATUS */
-	      		if( chdlc_udp_pkt->data[0] == 0) {
-
-	      	   	     	if( --rCount != 0) {
-		  			chdlc_udp_pkt->cblock.
-					return_code = COMMAND_OK;
-					mb->buffer_length = 1;
-		  			break;
-	   	    	     	} 
-	      		} 	
-	
-		default:
-			/* it's a board command */
-			mb->command = chdlc_udp_pkt->cblock.command;
-			mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
-			if (mb->buffer_length) {
-				memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
-							data, mb->buffer_length);
-	      		} 
-			/* run the command on the board */
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-			if (err != COMMAND_OK) {
-				break;
-			}
-
-			/* copy the result back to our buffer */
-	         	memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t)); 
-			
-			if (mb->buffer_length) {
-	         		memcpy(&chdlc_udp_pkt->data, &mb->data, 
-								mb->buffer_length); 
-	      		}
-
-		} /* end of switch */
-     	} /* end of else */
-
-     	/* Fill UDP TTL */
-	chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl; 
-
-     	len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
-	
-     	if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
-		if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
-			++ card->wandev.stats.tx_packets;
-			card->wandev.stats.tx_bytes += len;
-		}
-	} else {	
-	
-		/* Pass it up the stack
-    		   Allocate socket buffer */
-		if ((new_skb = dev_alloc_skb(len)) != NULL) {
-			/* copy data into new_skb */
-
- 	    		buf = skb_put(new_skb, len);
-  	    		memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
-
-            		/* Decapsulate pkt and pass it up the protocol stack */
-	    		new_skb->protocol = htons(ETH_P_IP);
-            		new_skb->dev = dev;
-	    		new_skb->mac.raw  = new_skb->data;
-	
-			netif_rx(new_skb);
-			dev->last_rx = jiffies;
-		} else {
-	    	
-			printk(KERN_INFO "%s: no socket buffers available!\n",
-					card->devname);
-  		}
-    	}
- 
-	chdlc_priv_area->udp_pkt_lgth = 0;
- 	
-	return 0;
-}
-
-/*============================================================================
- * Initialize Receive and Transmit Buffers.
- */
-
-static void init_chdlc_tx_rx_buff(sdla_t* card, struct net_device *dev)
-{
-	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
-	CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
-	CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
-	char err;
-	
-	mb->buffer_length = 0;
-	mb->command = READ_CHDLC_CONFIGURATION;
-	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-
-	if(err != COMMAND_OK) {
-		chdlc_error(card,err,mb);
-		return;
-	}
-
-	if(card->hw.type == SDLA_S514) {
-		tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
-                (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
-                            ptr_CHDLC_Tx_stat_el_cfg_struct));
-        	rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
-                (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
-                            ptr_CHDLC_Rx_stat_el_cfg_struct));
-
-       		/* Setup Head and Tails for buffers */
-        	card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
-                tx_config->base_addr_Tx_status_elements);
-        	card->u.c.txbuf_last = 
-		(CHDLC_DATA_TX_STATUS_EL_STRUCT *)  
-                card->u.c.txbuf_base +
-		(tx_config->number_Tx_status_elements - 1);
-
-        	card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
-                rx_config->base_addr_Rx_status_elements);
-        	card->u.c.rxbuf_last =
-		(CHDLC_DATA_RX_STATUS_EL_STRUCT *)
-                card->u.c.rxbuf_base +
-		(rx_config->number_Rx_status_elements - 1);
-
- 		/* Set up next pointer to be used */
-        	card->u.c.txbuf = (void *)(card->hw.dpmbase +
-                tx_config->next_Tx_status_element_to_use);
-        	card->u.c.rxmb = (void *)(card->hw.dpmbase +
-                rx_config->next_Rx_status_element_to_use);
-	}
-        else {
-                tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
-			(((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
-			ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
-
-                rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
-			(((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
-			ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
-
-                /* Setup Head and Tails for buffers */
-                card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
-		(tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
-                card->u.c.txbuf_last =
-		(CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
-		+ (tx_config->number_Tx_status_elements - 1);
-                card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
-		(rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
-                card->u.c.rxbuf_last = 
-		(CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
-		+ (rx_config->number_Rx_status_elements - 1);
-
-                 /* Set up next pointer to be used */
-                card->u.c.txbuf = (void *)(card->hw.dpmbase +
-		(tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
-                card->u.c.rxmb = (void *)(card->hw.dpmbase +
-		(rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
-        }
-
-        /* Setup Actual Buffer Start and end addresses */
-        card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
-        card->u.c.rx_top  = rx_config->end_addr_Rx_buffer;
-
-}
-
-/*=============================================================================
- * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
- * _TEST_COUNTER times.
- */
-static int intr_test( sdla_t* card)
-{
-	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
-	int err,i;
-
-	Intr_test_counter = 0;
-
-	/* The critical flag is unset because during initialization (if_open) 
-	 * we want the interrupts to be enabled so that when the wpc_isr is
-	 * called it does not exit due to critical flag set.
-	 */ 
-
-	err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
-
-	if (err == CMD_OK) { 
-		for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {	
-			mb->buffer_length  = 0;
-			mb->command = READ_CHDLC_CODE_VERSION;
-			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
-		}
-	}
-	else {
-		return err;
-	}
-
-	err = chdlc_set_intr_mode(card, 0);
-
-	if (err != CMD_OK)
-		return err;
-
-	return 0;
-}
-
-/*==============================================================================
- * Determine what type of UDP call it is. CPIPEAB ?
- */
-static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
-{
-	 chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
-
-	if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
-	   (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
-	   (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
-	   (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
-		return UDP_CPIPE_TYPE;
-	}
-	else return UDP_INVALID_TYPE;
-}
-
-/*============================================================================
- * Set PORT state.
- */
-static void port_set_state (sdla_t *card, int state)
-{
-	struct net_device *dev = card->wandev.dev;
-	chdlc_private_area_t *chdlc_priv_area = dev->priv;
-
-        if (card->u.c.state != state)
-        {
-                switch (state)
-                {
-                case WAN_CONNECTED:
-                        printk (KERN_INFO "%s: HDLC link connected!\n",
-                                card->devname);
-                      break;
-
-                case WAN_CONNECTING:
-                        printk (KERN_INFO "%s: HDLC link connecting...\n",
-                                card->devname);
-                        break;
-
-                case WAN_DISCONNECTED:
-                        printk (KERN_INFO "%s: HDLC link disconnected!\n",
-                                card->devname);
-                        break;
-                }
-
-                card->wandev.state = card->u.c.state = state;
-		chdlc_priv_area->common.state = state;
-        }
-}
-
-void s508_lock (sdla_t *card, unsigned long *smp_flags)
-{
-	spin_lock_irqsave(&card->wandev.lock, *smp_flags);
-        if (card->next){
-		/* It is ok to use spin_lock here, since we
-		 * already turned off interrupts */
-        	spin_lock(&card->next->wandev.lock);
-	}
-}
-
-void s508_unlock (sdla_t *card, unsigned long *smp_flags)
-{
-	if (card->next){
-		spin_unlock(&card->next->wandev.lock);
-	}
-	spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
-}
-
-
-
-/*===========================================================================
- * config_chdlc
- *
- *	Configure the chdlc protocol and enable communications.		
- *
- *   	The if_open() function binds this function to the poll routine.
- *      Therefore, this function will run every time the chdlc interface
- *      is brought up. We cannot run this function from the if_open 
- *      because if_open does not have access to the remote IP address.
- *      
- *	If the communications are not enabled, proceed to configure
- *      the card and enable communications.
- *
- *      If the communications are enabled, it means that the interface
- *      was shutdown by ether the user or driver. In this case, we 
- *      have to check that the IP addresses have not changed.  If
- *      the IP addresses have changed, we have to reconfigure the firmware
- *      and update the changed IP addresses.  Otherwise, just exit.
- *
- */
-
-static int config_chdlc (sdla_t *card)
-{
-	struct net_device *dev = card->wandev.dev;
-	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
-
-	if (card->u.c.comm_enabled){
-		chdlc_comm_disable(card);
-		port_set_state(card, WAN_DISCONNECTED);
-	}
-
-	if (set_chdlc_config(card)) {
-		printk(KERN_INFO "%s: CHDLC Configuration Failed!\n",
-				card->devname);
-		return 0;
-	}
-	init_chdlc_tx_rx_buff(card, dev);
-
-	/* Set interrupt mode and mask */
-        if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
-                		APP_INT_ON_GLOBAL_EXCEP_COND |
-                		APP_INT_ON_TX_FRAME |
-                		APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
-		printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
-				card->devname);
-		return 0;	
-        }
-	
-
-	/* Mask the Transmit and Timer interrupt */
-	flags->interrupt_info_struct.interrupt_permission &= 
-		~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
-
-
-	if (chdlc_comm_enable(card) != 0) {
-		printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
-				card->devname);
-		flags->interrupt_info_struct.interrupt_permission = 0;
-		card->u.c.comm_enabled=0;
-		chdlc_set_intr_mode(card,0);
-		return 0;
-	}
-
-	/* Initialize Rx/Tx buffer control fields */
-	port_set_state(card, WAN_CONNECTING);
-	return 0; 
-}
-
-
-static void send_ppp_term_request(struct net_device *dev)
-{
-	struct sk_buff *new_skb;
-	unsigned char *buf;
-
-	if ((new_skb = dev_alloc_skb(8)) != NULL) {
-		/* copy data into new_skb */
-
-		buf = skb_put(new_skb, 8);
-		sprintf(buf,"%c%c%c%c%c%c%c%c", 0xFF,0x03,0xC0,0x21,0x05,0x98,0x00,0x07);
-
-		/* Decapsulate pkt and pass it up the protocol stack */
-		new_skb->protocol = htons(ETH_P_WAN_PPP);
-		new_skb->dev = dev;
-		new_skb->mac.raw  = new_skb->data;
-
-		netif_rx(new_skb);
-		dev->last_rx = jiffies;
-	}
-}
-
-
-MODULE_LICENSE("GPL");
-
-/****** End ****************************************************************/
diff --git a/include/linux/sdla_asy.h b/include/linux/sdla_asy.h
deleted file mode 100644
index f622425..0000000
--- a/include/linux/sdla_asy.h
+++ /dev/null
@@ -1,226 +0,0 @@
-/*****************************************************************************
-* sdla_asy.h	Header file for the Sangoma S508/S514 asynchronous code API	
-*
-* Author: 	Gideon Hack 	
-*
-* Copyright:	(c) 2000 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.
-* ============================================================================
-*
-* Jan 28, 2000	Gideon Hack 	Initial Version
-*
-*****************************************************************************/
-
-
-#ifndef _WANPIPE_ASYNC_H
-#define _WANPIPE_ASYNC_H
-
-/* ----------------------------------------------------------------------------
- *                        Interface commands
- * --------------------------------------------------------------------------*/
-
-#define SET_ASY_CONFIGURATION		0xE2	/* set the asychronous operational configuration */
-#define READ_ASY_CONFIGURATION		0xE3	/* read the current asychronous operational configuration */
-#define ENABLE_ASY_COMMUNICATIONS	0xE4	/* enable asychronous communications */
-#define DISABLE_ASY_COMMUNICATIONS	0xE5	/* disable asychronous communications */
-#define READ_ASY_OPERATIONAL_STATS	0xE7	/* retrieve the asychronous operational statistics */
-#define FLUSH_ASY_OPERATIONAL_STATS	0xE8	/* flush the asychronous operational statistics */
-#define TRANSMIT_ASY_BREAK_SIGNAL	0xEC	/* transmit an asychronous break signal */
-
-
-
-/* ----------------------------------------------------------------------------
- *                     Return codes from interface commands
- * --------------------------------------------------------------------------*/
-
-#define COMMAND_INVALID_FOR_PORT	0x50	/* the command is invalid for the selected port */
-#define DISABLE_ASY_COMMS_BEFORE_CFG 	0xE1	/* communications must be disabled before setting the configuration */
-#define ASY_COMMS_ENABLED		0xE1	/* communications are currently enabled */
-#define ASY_COMMS_DISABLED		0xE1	/* communications are currently disabled */
-#define ASY_CFG_BEFORE_COMMS_ENABLED	0xE2	/* perform a SET_ASY_CONFIGURATION before enabling comms */
-#define LGTH_ASY_CFG_DATA_INVALID  	0xE2	/* the length of the passed configuration data is invalid */
-#define INVALID_ASY_CFG_DATA		0xE3	/* the passed configuration data is invalid */
-#define ASY_BREAK_SIGNAL_BUSY		0xEC	/* a break signal is being transmitted */
-
-
-
-/* ----------------------------------------------------------------------------
- *   Constants for the SET_ASY_CONFIGURATION/READ_ASY_CONFIGURATION command
- * --------------------------------------------------------------------------*/
-
-/* the asynchronous configuration structure */
-typedef struct {
-	unsigned long baud_rate			PACKED;							/* the baud rate */	
-	unsigned short line_config_options	PACKED;	/* line configuration options */
-	unsigned short modem_config_options	PACKED;	/* modem configuration options */
-	unsigned short asy_API_options		PACKED;	/* asynchronous API options */
-	unsigned short asy_protocol_options	PACKED; /* asynchronous protocol options */
-	unsigned short Tx_bits_per_char		PACKED;	/* number of bits per tx character */
-	unsigned short Rx_bits_per_char		PACKED;	/* number of bits per received character */
-	unsigned short stop_bits		PACKED;	/* number of stop bits per character */
-	unsigned short parity			PACKED;	/* parity definition */
-	unsigned short break_timer		PACKED;	/* the break signal timer */
-	unsigned short asy_Rx_inter_char_timer	PACKED;	/* the receive inter-character timer */
-	unsigned short asy_Rx_complete_length	PACKED;	/* the receive 'buffer complete' length */
-	unsigned short XON_char			PACKED;	/* the XON character */
-	unsigned short XOFF_char		PACKED;	/* the XOFF character */
-	unsigned short asy_statistics_options	PACKED;	/* async operational stat options */
-	unsigned long ptr_shared_mem_info_struct    PACKED;/* ptr to the shared memory area information structure */
-	unsigned long ptr_asy_Tx_stat_el_cfg_struct PACKED;/* ptr to the transmit status element configuration structure */
-	unsigned long ptr_asy_Rx_stat_el_cfg_struct PACKED;/* ptr to the receive status element configuration structure */
-} ASY_CONFIGURATION_STRUCT;
-
-/* permitted minimum and maximum values for setting the asynchronous configuration */
-#define MIN_ASY_BAUD_RATE		50	/* maximum baud rate */
-#define MAX_ASY_BAUD_RATE		250000	/* minimum baud rate */
-#define MIN_ASY_BITS_PER_CHAR		5	/* minimum number of bits per character */
-#define MAX_ASY_BITS_PER_CHAR		8	/* maximum number of bits per character */
-#define MIN_BREAK_TMR_VAL		0	/* minimum break signal timer */
-#define MAX_BREAK_TMR_VAL		5000	/* maximum break signal timer */
-#define MIN_ASY_RX_INTER_CHAR_TMR	0	/* minimum receive inter-character timer */
-#define MAX_ASY_RX_INTER_CHAR_TMR	30000	/* maximum receive inter-character timer */
-#define MIN_ASY_RX_CPLT_LENGTH		0	/* minimum receive 'length complete' value */
-#define MAX_ASY_RX_CPLT_LENGTH		2000	/* maximum receive 'length complete' value */
-
-/* bit settings for the 'asy_API_options' */
-#define ASY_RX_DATA_TRANSPARENT		0x0001	/* do not strip parity and unused bits from received characters */
-
-/* bit settings for the 'asy_protocol_options' */
-#define ASY_RTS_HS_FOR_RX		0x0001	/* RTS handshaking is used for reception control */
-#define ASY_XON_XOFF_HS_FOR_RX		0x0002	/* XON/XOFF handshaking is used for reception control */
-#define ASY_XON_XOFF_HS_FOR_TX		0x0004	/* XON/XOFF handshaking is used for transmission control */
-#define ASY_DCD_HS_FOR_TX		0x0008	/* DCD handshaking is used for transmission control */
-#define ASY_CTS_HS_FOR_TX		0x0020	/* CTS handshaking is used for transmission control */
-
-/* bit settings for the 'stop_bits' definition */
-#define ONE_STOP_BIT			1			/* representation for 1 stop bit */
-#define TWO_STOP_BITS			2			/* representation for 2 stop bits */
-#define ONE_AND_A_HALF_STOP_BITS	3			/* representation for 1.5 stop bits */
-
-/* bit settings for the 'parity' definition */
-#define NO_PARITY			0			/* representation for no parity */
-#define ODD_PARITY			1			/* representation for odd parity */
-#define EVEN_PARITY			2			/* representation for even parity */
-
-
-
-/* ----------------------------------------------------------------------------
- *    Constants for the READ_COMMS_ERROR_STATS command (asynchronous mode)
- * --------------------------------------------------------------------------*/
-
-/* the communications error statistics structure */
-typedef struct {
-	unsigned short Rx_overrun_err_count   	PACKED;	/* receiver overrun error count */
-	unsigned short Rx_parity_err_count	PACKED;	/* parity errors received count */
-	unsigned short Rx_framing_err_count	PACKED;	/* framing errors received count */
-	unsigned short comms_err_stat_reserved_1 PACKED;/* reserved for later use */
-	unsigned short comms_err_stat_reserved_2 PACKED;/* reserved for later use */
-	unsigned short comms_err_stat_reserved_3 PACKED;/* reserved for later use */
-	unsigned short comms_err_stat_reserved_4 PACKED;/* reserved for later use */
-	unsigned short comms_err_stat_reserved_5 PACKED;/* reserved for later use */
-	unsigned short DCD_state_change_count 	PACKED;	/* DCD state change count */
-	unsigned short CTS_state_change_count	PACKED;	/* CTS state change count */
-} ASY_COMMS_ERROR_STATS_STRUCT;
-
-
-
-/* ----------------------------------------------------------------------------
- *         Constants for the READ_ASY_OPERATIONAL_STATS command
- * --------------------------------------------------------------------------*/
-
-/* the asynchronous operational statistics structure */
-typedef struct {
-
-	/* Data transmission statistics */
-	unsigned long Data_blocks_Tx_count PACKED;/* number of blocks transmitted */
-	unsigned long Data_bytes_Tx_count  PACKED;/* number of bytes transmitted */
-	unsigned long Data_Tx_throughput   PACKED;/* transmit throughput */
-	unsigned long no_ms_for_Data_Tx_thruput_comp PACKED;/* millisecond time used for the Tx throughput computation */
-	unsigned long Tx_Data_discard_lgth_err_count PACKED;/* number of Data blocks discarded (length error) */
-	unsigned long reserved_Data_frm_Tx_stat1 PACKED;/* reserved for later use */
-	unsigned long reserved_Data_frm_Tx_stat2 PACKED;/* reserved for later use */
-	unsigned long reserved_Data_frm_Tx_stat3 PACKED;/* reserved for later use */
-
-	/* Data reception statistics */
-	unsigned long Data_blocks_Rx_count PACKED;/* number of blocks received */
-	unsigned long Data_bytes_Rx_count  PACKED;/* number of bytes received */
-	unsigned long Data_Rx_throughput   PACKED;/* receive throughput */
-	unsigned long no_ms_for_Data_Rx_thruput_comp PACKED;/* millisecond time used for the Rx throughput computation */
-	unsigned long Rx_Data_bytes_discard_count    PACKED;/* received Data bytes discarded */
-	unsigned long reserved_Data_frm_Rx_stat1     PACKED;/* reserved for later use */
-
-	/* handshaking protocol statistics */
-	unsigned short XON_chars_Tx_count	PACKED;	/* number of XON characters transmitted */
-	unsigned short XOFF_chars_Tx_count	PACKED;	/* number of XOFF characters transmitted */
-	unsigned short XON_chars_Rx_count	PACKED;	/* number of XON characters received */
-	unsigned short XOFF_chars_Rx_count	PACKED;	/* number of XOFF characters received */
-	unsigned short Tx_halt_modem_low_count	PACKED; /* number of times Tx halted (modem line low) */
-	unsigned short Rx_halt_RTS_low_count	PACKED;	/* number of times Rx halted by setting RTS low */
-	unsigned long reserved_handshaking_stat1 PACKED;/* reserved for later use */
-
-	/* break statistics */
-	unsigned short break_Tx_count	PACKED;	/* number of break sequences transmitted */
-	unsigned short break_Rx_count	PACKED;	/* number of break sequences received */
-	unsigned long reserved_break_stat1 PACKED;/* reserved for later use */
-
-	/* miscellaneous statistics */
-	unsigned long reserved_misc_stat1	PACKED;	/* reserved for later use */
-	unsigned long reserved_misc_stat2	PACKED;	/* reserved for later use */
-
-} ASY_OPERATIONAL_STATS_STRUCT;
-
-
-
-/* ----------------------------------------------------------------------------
- *                      Constants for Data transmission
- * --------------------------------------------------------------------------*/
-
-/* the Data block transmit status element configuration structure */
-typedef struct {
-	unsigned short number_Tx_status_elements PACKED;		/* number of transmit status elements */
-	unsigned long base_addr_Tx_status_elements PACKED;	/* base address of the transmit element list */
-	unsigned long next_Tx_status_element_to_use PACKED;	/* pointer to the next transmit element to be used */
-} ASY_TX_STATUS_EL_CFG_STRUCT;
-
-
-/* the Data block transmit status element structure */
-typedef struct {
-	unsigned char opp_flag PACKED;								/* opp flag */
-	unsigned short data_length PACKED;						/* length of the block to be transmitted */
-	unsigned char reserved_1 PACKED;							/* reserved for internal use */
-	unsigned long reserved_2 PACKED;							/* reserved for internal use */
-	unsigned long reserved_3 PACKED;							/* reserved for internal use */
-	unsigned long ptr_data_bfr PACKED;						/* pointer to the data area */
-} ASY_DATA_TX_STATUS_EL_STRUCT;
-
-
-
-/* ----------------------------------------------------------------------------
- *                      Constants for Data reception
- * --------------------------------------------------------------------------*/
-
-/* the Data block receive status element configuration structure */
-typedef struct {
-	unsigned short number_Rx_status_elements    PACKED;/* number of receive status elements */
-	unsigned long base_addr_Rx_status_elements  PACKED;/* base address of the receive element list */
-	unsigned long next_Rx_status_element_to_use PACKED;/* pointer to the next receive element to be used */
-	unsigned long base_addr_Rx_buffer	PACKED;/* base address of the receive data buffer */
-	unsigned long end_addr_Rx_buffer 	PACKED;/* end address of the receive data buffer */
-} ASY_RX_STATUS_EL_CFG_STRUCT;
-
-/* the Data block receive status element structure */
-typedef struct {
-	unsigned char opp_flag 		PACKED;	/* opp flag */
-	unsigned short data_length 	PACKED;	/* length of the received data block */
-	unsigned char reserved_1 	PACKED;	/* reserved for internal use */
-	unsigned short time_stamp 	PACKED; /* receive time stamp (HDLC_STREAMING_MODE) */
-	unsigned short data_buffered 	PACKED;	/* the number of data bytes still buffered */
-	unsigned long reserved_2 	PACKED;	/* reserved for internal use */
-	unsigned long ptr_data_bfr 	PACKED;	/* pointer to the data area */
-} ASY_DATA_RX_STATUS_EL_STRUCT;
-
-#endif
diff --git a/include/linux/sdla_chdlc.h b/include/linux/sdla_chdlc.h
deleted file mode 100644
index d2e35a2..0000000
--- a/include/linux/sdla_chdlc.h
+++ /dev/null
@@ -1,813 +0,0 @@
-/*************************************************************************
- sdla_chdlc.h	Sangoma Cisco HDLC firmware API definitions
-
- Author:      	Gideon Hack
-		Nenad Corbic <ncorbic@sangoma.com>	
-
- Copyright:	(c) 1995-2000 Sangoma Technologies Inc.
-
-		This program is free software; you can redistribute it and/or
-		modify it under the term 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.
-
-===========================================================================
-  Oct 04, 1999  Nenad Corbic    Updated API support
-  Jun 02, 1999  Gideon Hack     Changes for S514 usage.
-  Oct 28, 1998	Jaspreet Singh	Made changes for Dual Port CHDLC.
-  Jun 11, 1998	David Fong	Initial version.
-===========================================================================
-
- Organization
-	- Compatibility notes
-	- Constants defining the shared memory control block (mailbox)
-	- Interface commands
-	- Return code from interface commands
-	- Constants for the commands (structures for casting data)
-	- UDP Management constants and structures
-
-*************************************************************************/
-
-#ifndef _SDLA_CHDLC_H
-#  define _SDLC_CHDLC_H
-
-/*------------------------------------------------------------------------
-   Notes:
-
-	All structres defined in this file are byte-aligned.  
-
-	Compiler	Platform
-	------------------------
-	GNU C		Linux
-
-------------------------------------------------------------------------*/
-
-#ifndef	PACKED
-#define	PACKED __attribute__((packed))
-#endif	/* PACKED */
-
-
-/* ----------------------------------------------------------------------------
- *        Constants defining the shared memory control block (mailbox)
- * --------------------------------------------------------------------------*/
-
-#define PRI_BASE_ADDR_MB_STRUCT 	0xE000 	/* the base address of the mailbox structure on the adapter */
-#define SEC_BASE_ADDR_MB_STRUCT 	0xE800 	/* the base address of the mailbox structure on the adapter */
-#define SIZEOF_MB_DATA_BFR		2032	/* the size of the actual mailbox data area */
-#define NUMBER_MB_RESERVED_BYTES	0x0B	/* the number of reserved bytes in the mailbox header area */
-
-
-#define MIN_LGTH_CHDLC_DATA_CFG  	300 	/* min length of the CHDLC data field (for configuration purposes) */
-#define PRI_MAX_NO_DATA_BYTES_IN_FRAME  15354 /* PRIMARY - max length of the CHDLC data field */
-
-typedef struct {
-	unsigned char opp_flag PACKED;			/* the opp flag */
-	unsigned char command PACKED;			/* the user command */
-	unsigned short buffer_length PACKED;		/* the data length */
-  	unsigned char return_code PACKED;		/* the return code */
-	unsigned char MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED;	/* reserved for later */
-	unsigned char data[SIZEOF_MB_DATA_BFR] PACKED;	/* the data area */
-} CHDLC_MAILBOX_STRUCT;
-
-typedef struct {
-        pid_t                   pid_num PACKED;
-        CHDLC_MAILBOX_STRUCT     cmdarea PACKED;
-
-} CMDBLOCK_STRUCT;
-
-
-
-
-/* ----------------------------------------------------------------------------
- *                        Interface commands
- * --------------------------------------------------------------------------*/
-
-/* global interface commands */
-#define READ_GLOBAL_EXCEPTION_CONDITION	0x01
-#define SET_GLOBAL_CONFIGURATION	0x02
-#define READ_GLOBAL_CONFIGURATION	0x03
-#define READ_GLOBAL_STATISTICS		0x04
-#define FLUSH_GLOBAL_STATISTICS		0x05
-#define SET_MODEM_STATUS		0x06	/* set status of DTR or RTS */
-#define READ_MODEM_STATUS		0x07	/* read status of CTS and DCD */
-#define READ_COMMS_ERROR_STATS		0x08	
-#define FLUSH_COMMS_ERROR_STATS		0x09
-#define SET_TRACE_CONFIGURATION		0x0A	/* set the line trace config */
-#define READ_TRACE_CONFIGURATION	0x0B	/* read the line trace config */
-#define READ_TRACE_STATISTICS		0x0C	/* read the trace statistics */
-#define FLUSH_TRACE_STATISTICS		0x0D	/* flush the trace statistics */
-#define FT1_MONITOR_STATUS_CTRL		0x1C	/* set the status of the S508/FT1 monitoring */
-#define SET_FT1_CONFIGURATION		0x18	/* set the FT1 configuration */
-#define READ_FT1_CONFIGURATION		0x19	/* read the FT1 configuration */
-#define TRANSMIT_ASYNC_DATA_TO_FT1	0x1A	/* output asynchronous data to the FT1 */
-#define RECEIVE_ASYNC_DATA_FROM_FT1	0x1B	/* receive asynchronous data from the FT1 */
-#define FT1_MONITOR_STATUS_CTRL		0x1C	/* set the status of the FT1 monitoring */
-
-#define READ_FT1_OPERATIONAL_STATS	0x1D	/* read the S508/FT1 operational statistics */
-#define SET_FT1_MODE			0x1E	/* set the operational mode of the S508/FT1 module */
-
-/* CHDLC-level interface commands */
-#define READ_CHDLC_CODE_VERSION		0x20	
-#define READ_CHDLC_EXCEPTION_CONDITION	0x21	/* read exception condition from the adapter */
-#define SET_CHDLC_CONFIGURATION		0x22
-#define READ_CHDLC_CONFIGURATION	0x23
-#define ENABLE_CHDLC_COMMUNICATIONS	0x24
-#define DISABLE_CHDLC_COMMUNICATIONS	0x25
-#define READ_CHDLC_LINK_STATUS		0x26
-#define READ_CHDLC_OPERATIONAL_STATS	0x27
-#define FLUSH_CHDLC_OPERATIONAL_STATS	0x28
-#define SET_CHDLC_INTERRUPT_TRIGGERS	0x30	/* set application interrupt triggers */
-#define READ_CHDLC_INTERRUPT_TRIGGERS	0x31	/* read application interrupt trigger configuration */
-
-/* Special UDP drivers management commands */
-#define CPIPE_ENABLE_TRACING				0x50
-#define CPIPE_DISABLE_TRACING				0x51
-#define CPIPE_GET_TRACE_INFO				0x52
-#define CPIPE_GET_IBA_DATA				0x53
-#define CPIPE_FT1_READ_STATUS				0x54
-#define CPIPE_DRIVER_STAT_IFSEND			0x55
-#define CPIPE_DRIVER_STAT_INTR				0x56
-#define CPIPE_DRIVER_STAT_GEN				0x57
-#define CPIPE_FLUSH_DRIVER_STATS			0x58
-#define CPIPE_ROUTER_UP_TIME				0x59
-
-/* Driver specific commands for API */
-#define	CHDLC_READ_TRACE_DATA		0xE4	/* read trace data */
-#define TRACE_ALL                       0x00
-#define TRACE_PROT			0x01
-#define TRACE_DATA			0x02
-
-#define DISCARD_RX_ERROR_FRAMES	0x0001
-
-/* ----------------------------------------------------------------------------
- *                     Return codes from interface commands
- * --------------------------------------------------------------------------*/
-
-#define COMMAND_OK				0x00
-
-/* return codes from global interface commands */
-#define NO_GLOBAL_EXCEP_COND_TO_REPORT		0x01	/* there is no CHDLC exception condition to report */
-#define LGTH_GLOBAL_CFG_DATA_INVALID		0x01	/* the length of the passed global configuration data is invalid */
-#define LGTH_TRACE_CFG_DATA_INVALID		0x01	/* the length of the passed trace configuration data is invalid */
-#define IRQ_TIMEOUT_VALUE_INVALID		0x02	/* an invalid application IRQ timeout value was selected */
-#define TRACE_CONFIG_INVALID			0x02	/* the passed line trace configuration is invalid */
-#define ADAPTER_OPERATING_FREQ_INVALID		0x03	/* an invalid adapter operating frequency was selected */
-#define TRC_DEAC_TMR_INVALID			0x03	/* the trace deactivation timer is invalid */
-#define S508_FT1_ADPTR_NOT_PRESENT		0x0C	/* the S508/FT1 adapter is not present */
-#define INVALID_FT1_STATUS_SELECTION            0x0D    /* the S508/FT1 status selection is invalid */
-#define FT1_OP_STATS_NOT_ENABLED		0x0D    /* the FT1 operational statistics have not been enabled */
-#define FT1_OP_STATS_NOT_AVAILABLE		0x0E    /* the FT1 operational statistics are not currently available */
-#define S508_FT1_MODE_SELECTION_BUSY		0x0E	/* the S508/FT1 adapter is busy selecting the operational mode */
-
-/* return codes from command READ_GLOBAL_EXCEPTION_CONDITION */
-#define EXCEP_MODEM_STATUS_CHANGE		0x10		/* a modem status change occurred */
-#define EXCEP_TRC_DISABLED			0x11		/* the trace has been disabled */
-#define EXCEP_IRQ_TIMEOUT			0x12		/* IRQ timeout */
-
-/* return codes from CHDLC-level interface commands */
-#define NO_CHDLC_EXCEP_COND_TO_REPORT		0x21	/* there is no CHDLC exception condition to report */
-#define CHDLC_COMMS_DISABLED			0x21	/* communications are not currently enabled */
-#define CHDLC_COMMS_ENABLED			0x21	/* communications are currently enabled */
-#define DISABLE_CHDLC_COMMS_BEFORE_CFG		0x21	/* CHDLC communications must be disabled before setting the configuration */
-#define ENABLE_CHDLC_COMMS_BEFORE_CONN		0x21	/* communications must be enabled before using the CHDLC_CONNECT conmmand */
-#define CHDLC_CFG_BEFORE_COMMS_ENABLED		0x22	/* perform a SET_CHDLC_CONFIGURATION before enabling comms */
-#define LGTH_CHDLC_CFG_DATA_INVALID 		0x22	/* the length of the passed CHDLC configuration data is invalid */
-#define LGTH_INT_TRIGGERS_DATA_INVALID		0x22	/* the length of the passed interrupt trigger data is invalid */
-#define INVALID_IRQ_SELECTED			0x23	/* in invalid IRQ was selected in the SET_CHDLC_INTERRUPT_TRIGGERS */
-#define INVALID_CHDLC_CFG_DATA			0x23	/* the passed CHDLC configuration data is invalid */
-#define IRQ_TMR_VALUE_INVALID			0x24	/* an invalid application IRQ timer value was selected */
-#define LARGER_PERCENT_TX_BFR_REQUIRED		0x24	/* a larger Tx buffer percentage is required */
-#define LARGER_PERCENT_RX_BFR_REQUIRED		0x25	/* a larger Rx buffer percentage is required */
-#define S514_BOTH_PORTS_SAME_CLK_MODE		0x26	/* S514 - both ports must have same clock mode */
-#define INVALID_CMND_HDLC_STREAM_MODE           0x4E    /* the CHDLC interface command is invalid for HDLC streaming mode */
-#define INVALID_CHDLC_COMMAND			0x4F	/* the defined CHDLC interface command is invalid */
-
-/* return codes from command READ_CHDLC_EXCEPTION_CONDITION */
-#define EXCEP_LINK_ACTIVE			0x30	/* the CHDLC link has become active */
-#define EXCEP_LINK_INACTIVE_MODEM		0x31	/* the CHDLC link has become inactive (modem status) */
-#define EXCEP_LINK_INACTIVE_KPALV		0x32	/* the CHDLC link has become inactive (keepalive status) */
-#define EXCEP_IP_ADDRESS_DISCOVERED		0x33	/* the IP address has been discovered */
-#define EXCEP_LOOPBACK_CONDITION		0x34	/* a loopback condition has occurred */
-
-
-/* return code from command CHDLC_SEND_WAIT and CHDLC_SEND_NO_WAIT */
-#define LINK_DISCONNECTED			0x21
-#define NO_TX_BFRS_AVAIL			0x24
-
-
-/* ----------------------------------------------------------------------------
- * Constants for the SET_GLOBAL_CONFIGURATION/READ_GLOBAL_CONFIGURATION commands
- * --------------------------------------------------------------------------*/
-
-/* the global configuration structure */
-typedef struct {
-	unsigned short adapter_config_options PACKED;	/* adapter config options */
-	unsigned short app_IRQ_timeout PACKED;		/* application IRQ timeout */
-	unsigned long adapter_operating_frequency PACKED;	/* adapter operating frequency */
-} GLOBAL_CONFIGURATION_STRUCT;
-
-/* settings for the 'app_IRQ_timeout' */
-#define MAX_APP_IRQ_TIMEOUT_VALUE	5000	/* the maximum permitted IRQ timeout */
-
-
-
-/* ----------------------------------------------------------------------------
- *             Constants for the READ_GLOBAL_STATISTICS command
- * --------------------------------------------------------------------------*/
-
-/* the global statistics structure */
-typedef struct {
-	unsigned short app_IRQ_timeout_count PACKED;
-} GLOBAL_STATS_STRUCT;
-
-
-
-/* ----------------------------------------------------------------------------
- *             Constants for the READ_COMMS_ERROR_STATS command
- * --------------------------------------------------------------------------*/
-
-/* the communications error statistics structure */
-typedef struct {
-	unsigned short Rx_overrun_err_count PACKED;
-	unsigned short CRC_err_count PACKED;	/* receiver CRC error count */
-	unsigned short Rx_abort_count PACKED; 	/* abort frames recvd count */
-	unsigned short Rx_dis_pri_bfrs_full_count PACKED;/* receiver disabled */
-	unsigned short comms_err_stat_reserved_1 PACKED;/* reserved for later */
-	unsigned short sec_Tx_abort_msd_Tx_int_count PACKED; /* secondary - abort frames transmitted count (missed Tx interrupt) */
-	unsigned short missed_Tx_und_int_count PACKED;	/* missed tx underrun interrupt count */
-        unsigned short sec_Tx_abort_count PACKED;   /*secondary-abort frames tx count */
-	unsigned short DCD_state_change_count PACKED; /* DCD state change */
-	unsigned short CTS_state_change_count PACKED; /* CTS state change */
-} COMMS_ERROR_STATS_STRUCT;
-
-
-
-/* ----------------------------------------------------------------------------
- *                  Constants used for line tracing
- * --------------------------------------------------------------------------*/
-
-/* the trace configuration structure (SET_TRACE_CONFIGURATION/READ_TRACE_CONFIGURATION commands) */
-typedef struct {
-	unsigned char trace_config PACKED;		/* trace configuration */
-	unsigned short trace_deactivation_timer PACKED;	/* trace deactivation timer */
-	unsigned long ptr_trace_stat_el_cfg_struct PACKED;	/* a pointer to the line trace element configuration structure */
-} LINE_TRACE_CONFIG_STRUCT;
-
-/* 'trace_config' bit settings */
-#define TRACE_INACTIVE		0x00	/* trace is inactive */
-#define TRACE_ACTIVE		0x01	/* trace is active */
-#define TRACE_DELAY_MODE	0x04	/* operate the trace in delay mode */
-#define TRACE_DATA_FRAMES	0x08	/* trace Data frames */
-#define TRACE_SLARP_FRAMES	0x10	/* trace SLARP frames */
-#define TRACE_CDP_FRAMES	0x20	/* trace CDP frames */
-
-/* the line trace status element configuration structure */
-typedef struct {
-	unsigned short number_trace_status_elements PACKED;	/* number of line trace elements */
-	unsigned long base_addr_trace_status_elements PACKED;	/* base address of the trace element list */
-	unsigned long next_trace_element_to_use PACKED;	/* pointer to the next trace element to be used */
-	unsigned long base_addr_trace_buffer PACKED;		/* base address of the trace data buffer */
-	unsigned long end_addr_trace_buffer PACKED;		/* end address of the trace data buffer */
-} TRACE_STATUS_EL_CFG_STRUCT;
-
-/* the line trace status element structure */
-typedef struct {
-	unsigned char opp_flag PACKED;			/* opp flag */
-	unsigned short trace_length PACKED;		/* trace length */
-	unsigned char trace_type PACKED;		/* trace type */
-	unsigned short trace_time_stamp PACKED;	/* time stamp */
-	unsigned short trace_reserved_1 PACKED;	/* reserved for later use */
-	unsigned long trace_reserved_2 PACKED;		/* reserved for later use */
-	unsigned long ptr_data_bfr PACKED;		/* ptr to the trace data buffer */
-} TRACE_STATUS_ELEMENT_STRUCT;
-
-/* "trace_type" bit settings */
-#define TRACE_INCOMING 			0x00
-#define TRACE_OUTGOINGING 		0x01
-#define TRACE_INCOMING_ABORTED 		0x10
-#define TRACE_INCOMING_CRC_ERROR 	0x20
-#define TRACE_INCOMING_OVERRUN_ERROR 	0x40
-
-
-
-/* the line trace statistics structure */
-typedef struct {
-	unsigned long frames_traced_count PACKED;	/* number of frames traced */
-	unsigned long trc_frms_not_recorded_count PACKED;	/* number of trace frames discarded */
-} LINE_TRACE_STATS_STRUCT;
-
-
-/* ----------------------------------------------------------------------------
- *               Constants for the FT1_MONITOR_STATUS_CTRL command
- * --------------------------------------------------------------------------*/
-
-#define DISABLE_FT1_STATUS_STATISTICS	0x00    /* disable the FT1 status and statistics monitoring */
-#define ENABLE_READ_FT1_STATUS		0x01    /* read the FT1 operational status */
-#define ENABLE_READ_FT1_OP_STATS	0x02    /* read the FT1 operational statistics */
-#define FLUSH_FT1_OP_STATS		0x04 	/* flush the FT1 operational statistics */
-
-
-
-
-/* ----------------------------------------------------------------------------
- *               Constants for the SET_CHDLC_CONFIGURATION command
- * --------------------------------------------------------------------------*/
-
-/* the CHDLC configuration structure */
-typedef struct {
-	unsigned long baud_rate PACKED;		/* the baud rate */	
-	unsigned short line_config_options PACKED;	/* line configuration options */
-	unsigned short modem_config_options PACKED;	/* modem configration options */
-	unsigned short modem_status_timer PACKED;	/* timer for monitoring modem status changes */
-	unsigned short CHDLC_API_options PACKED;	/* CHDLC API options */
-	unsigned short CHDLC_protocol_options PACKED;	/* CHDLC protocol options */
-	unsigned short percent_data_buffer_for_Tx PACKED;	/* percentage data buffering used for Tx */
-	unsigned short CHDLC_statistics_options PACKED;	/* CHDLC operational statistics options */
-	unsigned short max_CHDLC_data_field_length PACKED;	/* the maximum length of the CHDLC Data field */
-	unsigned short transmit_keepalive_timer PACKED;		/* the transmit keepalive timer */
-	unsigned short receive_keepalive_timer PACKED;		/* the receive keepalive timer */
-	unsigned short keepalive_error_tolerance PACKED;	/* the receive keepalive error tolerance */
-	unsigned short SLARP_request_timer PACKED;		/* the SLARP request timer */
-	unsigned long IP_address PACKED;			/* the IP address */
-	unsigned long IP_netmask PACKED;			/* the IP netmask */
-	unsigned long ptr_shared_mem_info_struct PACKED;	/* a pointer to the shared memory area information structure */
-	unsigned long ptr_CHDLC_Tx_stat_el_cfg_struct PACKED;	/* a pointer to the transmit status element configuration structure */
-	unsigned long ptr_CHDLC_Rx_stat_el_cfg_struct PACKED;	/* a pointer to the receive status element configuration structure */
-} CHDLC_CONFIGURATION_STRUCT;
-
-/* settings for the 'line_config_options' */
-#define INTERFACE_LEVEL_V35					0x0000 /* V.35 interface level */
-#define INTERFACE_LEVEL_RS232					0x0001 /* RS-232 interface level */
-
-/* settings for the 'modem_config_options' */
-
-#define DONT_RAISE_DTR_RTS_ON_EN_COMMS		0x0001
-/* don't automatically raise DTR and RTS when performing an
-   ENABLE_CHDLC_COMMUNICATIONS command */
-
-#define DONT_REPORT_CHG_IN_MODEM_STAT 		0x0002
-/* don't report changes in modem status to the application */
-
-
-/* bit settings for the 'CHDLC_protocol_options' byte */
-
-#define IGNORE_DCD_FOR_LINK_STAT		0x0001
-/* ignore DCD in determining the CHDLC link status */
-
-#define IGNORE_CTS_FOR_LINK_STAT		0x0002
-/* ignore CTS in determining the CHDLC link status */
-
-#define IGNORE_KPALV_FOR_LINK_STAT		0x0004
-/* ignore keepalive frames in determining the CHDLC link status */ 
-
-#define SINGLE_TX_BUFFER			0x4000 
-/* configure a single transmit buffer */
-
-#define HDLC_STREAMING_MODE			0x8000
-
-/*   settings for the 'CHDLC_statistics_options' */
-
-#define CHDLC_TX_DATA_BYTE_COUNT_STAT		0x0001
-/* record the number of Data bytes transmitted */
-
-#define CHDLC_RX_DATA_BYTE_COUNT_STAT		0x0002
-/* record the number of Data bytes received */
-
-#define CHDLC_TX_THROUGHPUT_STAT		0x0004
-/* compute the Data frame transmit throughput */
-
-#define CHDLC_RX_THROUGHPUT_STAT		0x0008
-/* compute the Data frame receive throughput */
-
-
-/* permitted minimum and maximum values for setting the CHDLC configuration */
-#define PRI_MAX_BAUD_RATE_S508	2666666 /* PRIMARY   - maximum baud rate (S508) */
-#define SEC_MAX_BAUD_RATE_S508	258064 	/* SECONDARY - maximum baud rate (S508) */
-#define PRI_MAX_BAUD_RATE_S514  2750000 /* PRIMARY   - maximum baud rate (S508) */
-#define SEC_MAX_BAUD_RATE_S514  515625  /* SECONDARY - maximum baud rate (S508) */
- 
-#define MIN_MODEM_TIMER	0			/* minimum modem status timer */
-#define MAX_MODEM_TIMER	5000			/* maximum modem status timer */
-
-#define SEC_MAX_NO_DATA_BYTES_IN_FRAME  2048 /* SECONDARY - max length of the CHDLC data field */
-
-#define MIN_Tx_KPALV_TIMER	0	  /* minimum transmit keepalive timer */
-#define MAX_Tx_KPALV_TIMER	60000	  /* maximum transmit keepalive timer */
-#define DEFAULT_Tx_KPALV_TIMER	10000	  /* default transmit keepalive timer */
-
-#define MIN_Rx_KPALV_TIMER	10	  /* minimum receive keepalive timer */
-#define MAX_Rx_KPALV_TIMER	60000	  /* maximum receive keepalive timer */
-#define DEFAULT_Rx_KPALV_TIMER	10000	  /* default receive keepalive timer */
-
-#define MIN_KPALV_ERR_TOL	1	  /* min kpalv error tolerance count */
-#define MAX_KPALV_ERR_TOL	20	  /* max kpalv error tolerance count */
-#define DEFAULT_KPALV_ERR_TOL	3	  /* default value */
-
-#define MIN_SLARP_REQ_TIMER	0	  /* min transmit SLARP Request timer */
-#define MAX_SLARP_REQ_TIMER	60000	  /* max transmit SLARP Request timer */
-#define DEFAULT_SLARP_REQ_TIMER	0	  /* default value -- no SLARP */
-
-
-
-/* ----------------------------------------------------------------------------
- *             Constants for the READ_CHDLC_LINK_STATUS command
- * --------------------------------------------------------------------------*/
-
-/* the CHDLC status structure */
-typedef struct {
-	unsigned char CHDLC_link_status PACKED;	/* CHDLC link status */
-	unsigned char no_Data_frms_for_app PACKED;	/* number of Data frames available for the application */
-	unsigned char receiver_status PACKED;	/* enabled/disabled */
-	unsigned char SLARP_state PACKED;	/* internal SLARP state */
-} CHDLC_LINK_STATUS_STRUCT;
-
-/* settings for the 'CHDLC_link_status' variable */
-#define CHDLC_LINK_INACTIVE		0x00	/* the CHDLC link is inactive */
-#define CHDLC_LINK_ACTIVE		0x01	/* the CHDLC link is active */
-
-
-
-/* ----------------------------------------------------------------------------
- *           Constants for the READ_CHDLC_OPERATIONAL_STATS command
- * --------------------------------------------------------------------------*/
-
-/* the CHDLC operational statistics structure */
-typedef struct {
-
-	/* Data frame transmission statistics */
-	unsigned long Data_frames_Tx_count PACKED;	/* # of frames transmitted */
-	unsigned long Data_bytes_Tx_count PACKED; 	/* # of bytes transmitted */
-	unsigned long Data_Tx_throughput PACKED;	/* transmit throughput */
-	unsigned long no_ms_for_Data_Tx_thruput_comp PACKED;	/* millisecond time used for the Tx throughput computation */
-	unsigned long Tx_Data_discard_lgth_err_count PACKED;	/* number of Data frames discarded (length error) */
-	unsigned long reserved_Data_frm_Tx_stat1 PACKED;	/* reserved for later */
-	unsigned long reserved_Data_frm_Tx_stat2 PACKED;	/* reserved for later */
-	unsigned long reserved_Data_frm_Tx_stat3 PACKED;	/* reserved for later */
-
-	/* Data frame reception statistics */
-	unsigned long Data_frames_Rx_count PACKED;	/* number of frames received */
-	unsigned long Data_bytes_Rx_count PACKED;	/* number of bytes received */
-	unsigned long Data_Rx_throughput PACKED;	/* receive throughput */
-	unsigned long no_ms_for_Data_Rx_thruput_comp PACKED;	/* millisecond time used for the Rx throughput computation */
-	unsigned long Rx_Data_discard_short_count PACKED;	/* received Data frames discarded (too short) */
-	unsigned long Rx_Data_discard_long_count PACKED;	/* received Data frames discarded (too long) */
-	unsigned long Rx_Data_discard_inactive_count PACKED;	/* received Data frames discarded (link inactive) */
-	unsigned long reserved_Data_frm_Rx_stat1 PACKED;	/* reserved for later */
-
-	/* SLARP frame transmission/reception statistics */
-	unsigned long CHDLC_SLARP_REQ_Tx_count PACKED;		/* number of SLARP Request frames transmitted */
-	unsigned long CHDLC_SLARP_REQ_Rx_count PACKED;		/* number of SLARP Request frames received */
-	unsigned long CHDLC_SLARP_REPLY_Tx_count PACKED;	/* number of SLARP Reply frames transmitted */
-	unsigned long CHDLC_SLARP_REPLY_Rx_count PACKED;	/* number of SLARP Reply frames received */
-	unsigned long CHDLC_SLARP_KPALV_Tx_count PACKED;	/* number of SLARP keepalive frames transmitted */
-	unsigned long CHDLC_SLARP_KPALV_Rx_count PACKED;	/* number of SLARP keepalive frames received */
-	unsigned long reserved_SLARP_stat1 PACKED;		/* reserved for later */
-	unsigned long reserved_SLARP_stat2 PACKED;		/* reserved for later */
-
-	/* CDP frame transmission/reception statistics */
-	unsigned long CHDLC_CDP_Tx_count PACKED;		/* number of CDP frames transmitted */
-	unsigned long CHDLC_CDP_Rx_count PACKED;		/* number of CDP frames received */
-	unsigned long reserved_CDP_stat1 PACKED;		/* reserved for later */
-	unsigned long reserved_CDP_stat2 PACKED;		/* reserved for later */
-	unsigned long reserved_CDP_stat3 PACKED;		/* reserved for later */
-	unsigned long reserved_CDP_stat4 PACKED;		/* reserved for later */
-	unsigned long reserved_CDP_stat5 PACKED;		/* reserved for later */
-	unsigned long reserved_CDP_stat6 PACKED;		/* reserved for later */
-
-	/* Incoming frames with a format error statistics */
-	unsigned short Rx_frm_incomp_CHDLC_hdr_count PACKED;	/* frames received of with incomplete Cisco HDLC header */
-	unsigned short Rx_frms_too_long_count PACKED;		/* frames received of excessive length count */
-	unsigned short Rx_invalid_CHDLC_addr_count PACKED;	/* frames received with an invalid CHDLC address count */
-	unsigned short Rx_invalid_CHDLC_ctrl_count PACKED;	/* frames received with an invalid CHDLC control field count */
-	unsigned short Rx_invalid_CHDLC_type_count PACKED;	/* frames received of an invalid CHDLC frame type count */
-	unsigned short Rx_SLARP_invalid_code_count PACKED;	/* SLARP frame received with an invalid packet code */
-	unsigned short Rx_SLARP_Reply_bad_IP_addr PACKED;	/* SLARP Reply received - bad IP address */
-	unsigned short Rx_SLARP_Reply_bad_netmask PACKED;	/* SLARP Reply received - bad netmask */
-	unsigned long reserved_frm_format_err1 PACKED;		/* reserved for later */
-	unsigned long reserved_frm_format_err2 PACKED;		/* reserved for later */
-	unsigned long reserved_frm_format_err3 PACKED;		/* reserved for later */
-	unsigned long reserved_frm_format_err4 PACKED;		/* reserved for later */
-
-	/* CHDLC timeout/retry statistics */
-	unsigned short SLARP_Rx_keepalive_TO_count PACKED;	/* timeout count for incoming SLARP frames */
-	unsigned short SLARP_Request_TO_count PACKED;		/* timeout count for SLARP Request frames */
-	unsigned long To_retry_reserved_stat1 PACKED;		/* reserved for later */
-	unsigned long To_retry_reserved_stat2 PACKED;		/* reserved for later */
-	unsigned long To_retry_reserved_stat3 PACKED;		/* reserved for later */
-
-	/* CHDLC link active/inactive and loopback statistics */
-	unsigned short link_active_count PACKED;		/* number of times that the link went active */
-	unsigned short link_inactive_modem_count PACKED;	/* number of times that the link went inactive (modem failure) */
-	unsigned short link_inactive_keepalive_count PACKED;	/* number of times that the link went inactive (keepalive failure) */
-	unsigned short link_looped_count PACKED;		/* link looped count */
-	unsigned long link_status_reserved_stat1 PACKED;	/* reserved for later use */
-	unsigned long link_status_reserved_stat2 PACKED;	/* reserved for later use */
-
-	/* miscellaneous statistics */
-	unsigned long reserved_misc_stat1 PACKED;		/* reserved for later */
-	unsigned long reserved_misc_stat2 PACKED;		/* reserved for later */
-	unsigned long reserved_misc_stat3 PACKED;		/* reserved for later */
-	unsigned long reserved_misc_stat4 PACKED;		/* reserved for later */
-
-} CHDLC_OPERATIONAL_STATS_STRUCT;
-
-
-
-/* ----------------------------------------------------------------------------
- *                 Constants for using application interrupts
- * --------------------------------------------------------------------------*/
-
-/* the structure used for the SET_CHDLC_INTERRUPT_TRIGGERS/READ_CHDLC_INTERRUPT_TRIGGERS command */
-typedef struct {
-	unsigned char CHDLC_interrupt_triggers PACKED;	/* CHDLC interrupt trigger configuration */
-	unsigned char IRQ PACKED;			/* IRQ to be used */
-	unsigned short interrupt_timer PACKED;		/* interrupt timer */
-	unsigned short misc_interrupt_bits PACKED;	/* miscellaneous bits */
-} CHDLC_INT_TRIGGERS_STRUCT;
-
-/* 'CHDLC_interrupt_triggers' bit settings */
-#define APP_INT_ON_RX_FRAME		0x01	/* interrupt on Data frame reception */
-#define APP_INT_ON_TX_FRAME		0x02	/* interrupt when an Data frame may be transmitted */
-#define APP_INT_ON_COMMAND_COMPLETE	0x04	/* interrupt when an interface command is complete */
-#define APP_INT_ON_TIMER		0x08	/* interrupt on a defined millisecond timeout */
-#define APP_INT_ON_GLOBAL_EXCEP_COND 	0x10	/* interrupt on a global exception condition */
-#define APP_INT_ON_CHDLC_EXCEP_COND	0x20	/* interrupt on an CHDLC exception condition */
-#define APP_INT_ON_TRACE_DATA_AVAIL	0x80	/* interrupt when trace data is available */
-
-/* interrupt types indicated at 'interrupt_type' byte of the INTERRUPT_INFORMATION_STRUCT */
-#define NO_APP_INTS_PEND		0x00	/* no interrups are pending */
-#define RX_APP_INT_PEND			0x01	/* a receive interrupt is pending */
-#define TX_APP_INT_PEND			0x02	/* a transmit interrupt is pending */
-#define COMMAND_COMPLETE_APP_INT_PEND	0x04	/* a 'command complete' interrupt is pending */
-#define TIMER_APP_INT_PEND		0x08	/* a timer interrupt is pending */
-#define GLOBAL_EXCEP_COND_APP_INT_PEND 	0x10	/* a global exception condition interrupt is pending */
-#define CHDLC_EXCEP_COND_APP_INT_PEND 	0x20	/* an CHDLC exception condition interrupt is pending */
-#define TRACE_DATA_AVAIL_APP_INT_PEND	0x80	/* a trace data available interrupt is pending */
-
-
-/* modem status changes */
-#define DCD_HIGH			0x08
-#define CTS_HIGH			0x20
-
-
-/* ----------------------------------------------------------------------------
- *                   Constants for Data frame transmission
- * --------------------------------------------------------------------------*/
-
-/* the Data frame transmit status element configuration structure */
-typedef struct {
-	unsigned short number_Tx_status_elements PACKED;	/* number of transmit status elements */
-	unsigned long base_addr_Tx_status_elements PACKED;	/* base address of the transmit element list */
-	unsigned long next_Tx_status_element_to_use PACKED;	/* pointer to the next transmit element to be used */
-} CHDLC_TX_STATUS_EL_CFG_STRUCT;
-
-/* the Data frame transmit status element structure */
-typedef struct {
-	unsigned char opp_flag PACKED;		/* opp flag */
-	unsigned short frame_length PACKED;	/* length of the frame to be transmitted */
-	unsigned char reserved_1 PACKED;	/* reserved for internal use */
-	unsigned long reserved_2 PACKED;	/* reserved for internal use */
-	unsigned long reserved_3 PACKED;	/* reserved for internal use */
-	unsigned long ptr_data_bfr PACKED;	/* pointer to the data area */
-} CHDLC_DATA_TX_STATUS_EL_STRUCT;
-
-
-
-/* ----------------------------------------------------------------------------
- *                   Constants for Data frame reception
- * --------------------------------------------------------------------------*/
-
-/* the Data frame receive status element configuration structure */
-typedef struct {
-	unsigned short number_Rx_status_elements PACKED;	/* number of receive status elements */
-	unsigned long base_addr_Rx_status_elements PACKED;	/* base address of the receive element list */
-	unsigned long next_Rx_status_element_to_use PACKED;	/* pointer to the next receive element to be used */
-	unsigned long base_addr_Rx_buffer PACKED;		/* base address of the receive data buffer */
-	unsigned long end_addr_Rx_buffer PACKED;		/* end address of the receive data buffer */
-} CHDLC_RX_STATUS_EL_CFG_STRUCT;
-
-/* the Data frame receive status element structure */
-typedef struct {
-	unsigned char opp_flag PACKED;		/* opp flag */
-	unsigned short frame_length PACKED;   /* length of the received frame */
-        unsigned char error_flag PACKED; /* frame errors (HDLC_STREAMING_MODE)*/
-        unsigned short time_stamp PACKED; /* receive time stamp (HDLC_STREAMING_MODE) */
-        unsigned long reserved_1 PACKED; 	/* reserved for internal use */
-        unsigned short reserved_2 PACKED; 	/* reserved for internal use */
-        unsigned long ptr_data_bfr PACKED;	/* pointer to the data area */
-} CHDLC_DATA_RX_STATUS_EL_STRUCT;
-
-
-
-/* ----------------------------------------------------------------------------
- *         Constants defining the shared memory information area
- * --------------------------------------------------------------------------*/
-
-/* the global information structure */
-typedef struct {
- 	unsigned char global_status PACKED;		/* global status */
- 	unsigned char modem_status PACKED;		/* current modem status */
- 	unsigned char global_excep_conditions PACKED;	/* global exception conditions */
-	unsigned char glob_info_reserved[5] PACKED;	/* reserved */
-	unsigned char codename[4] PACKED;		/* Firmware name */
-	unsigned char codeversion[4] PACKED;		/* Firmware version */
-} GLOBAL_INFORMATION_STRUCT;
-
-/* the CHDLC information structure */
-typedef struct {
-	unsigned char CHDLC_status PACKED;		/* CHDLC status */
- 	unsigned char CHDLC_excep_conditions PACKED;	/* CHDLC exception conditions */
-	unsigned char CHDLC_info_reserved[14] PACKED;	/* reserved */
-} CHDLC_INFORMATION_STRUCT;
-
-/* the interrupt information structure */
-typedef struct {
- 	unsigned char interrupt_type PACKED;		/* type of interrupt triggered */
- 	unsigned char interrupt_permission PACKED;	/* interrupt permission mask */
-	unsigned char int_info_reserved[14] PACKED;	/* reserved */
-} INTERRUPT_INFORMATION_STRUCT;
-
-/* the S508/FT1 information structure */
-typedef struct {
- 	unsigned char parallel_port_A_input PACKED;	/* input - parallel port A */
- 	unsigned char parallel_port_B_input PACKED;	/* input - parallel port B */
-	unsigned char FT1_info_reserved[14] PACKED;	/* reserved */
-} FT1_INFORMATION_STRUCT;
-
-/* the shared memory area information structure */
-typedef struct {
-	GLOBAL_INFORMATION_STRUCT global_info_struct PACKED;		/* the global information structure */
-	CHDLC_INFORMATION_STRUCT CHDLC_info_struct PACKED;		/* the CHDLC information structure */
-	INTERRUPT_INFORMATION_STRUCT interrupt_info_struct PACKED;	/* the interrupt information structure */
-	FT1_INFORMATION_STRUCT FT1_info_struct PACKED;			/* the S508/FT1 information structure */
-} SHARED_MEMORY_INFO_STRUCT;
-
-/* ----------------------------------------------------------------------------
- *        UDP Management constants and structures 
- * --------------------------------------------------------------------------*/
-
-/* The embedded control block for UDP mgmt 
-   This is essentially a mailbox structure, without the large data field */
-
-typedef struct {
-        unsigned char  opp_flag PACKED;                  /* the opp flag */
-        unsigned char  command PACKED;                   /* the user command */
-        unsigned short buffer_length PACKED;             /* the data length */
-        unsigned char  return_code PACKED;               /* the return code */
-	unsigned char  MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED;	/* reserved for later */
-} cblock_t;
-
-
-/* UDP management packet layout (data area of ip packet) */
-/*
-typedef struct {
-	unsigned char		signature[8]	PACKED;
-	unsigned char		request_reply	PACKED;
-	unsigned char		id		PACKED;
-	unsigned char		reserved[6]	PACKED;
-	cblock_t		cblock		PACKED;
-	unsigned char		num_frames	PACKED;
-	unsigned char		ismoredata	PACKED;
-	unsigned char 		data[SIZEOF_MB_DATA_BFR] 	PACKED;
-} udp_management_packet_t;
-
-*/
-
-typedef struct {
-	unsigned char		num_frames	PACKED;
-	unsigned char		ismoredata	PACKED;
-} trace_info_t;
-
-typedef struct {
-	ip_pkt_t 		ip_pkt		PACKED;
-	udp_pkt_t		udp_pkt		PACKED;
-	wp_mgmt_t		wp_mgmt		PACKED;
-	cblock_t                cblock          PACKED;
-	trace_info_t       	trace_info      PACKED;
-	unsigned char           data[SIZEOF_MB_DATA_BFR]      PACKED;
-} chdlc_udp_pkt_t;
-
-typedef struct ft1_exec_cmd{
-	unsigned char  command PACKED;                   /* the user command */
-        unsigned short buffer_length PACKED;             /* the data length */
-        unsigned char  return_code PACKED;               /* the return code */
-	unsigned char  MB_reserved[NUMBER_MB_RESERVED_BYTES] PACKED;
-} ft1_exec_cmd_t;
-
-typedef struct {
-	unsigned char  opp_flag 			PACKED;
-	ft1_exec_cmd_t cmd				PACKED;
-	unsigned char  data[SIZEOF_MB_DATA_BFR]      	PACKED;
-} ft1_exec_t;
-
-#define UDPMGMT_SIGNATURE	"CTPIPEAB"
-
-
-/* UDP/IP packet (for UDP management) layout */
-/*
-typedef struct {
-	unsigned char	reserved[2]	PACKED;
-	unsigned short	ip_length	PACKED;
-	unsigned char	reserved2[4]	PACKED;
-	unsigned char	ip_ttl		PACKED;
-	unsigned char	ip_protocol	PACKED;
-	unsigned short	ip_checksum	PACKED;
-	unsigned long	ip_src_address	PACKED;
-	unsigned long	ip_dst_address	PACKED;
-	unsigned short	udp_src_port	PACKED;
-	unsigned short	udp_dst_port	PACKED;
-	unsigned short	udp_length	PACKED;
-	unsigned short	udp_checksum	PACKED;
-	udp_management_packet_t um_packet PACKED;
-} ip_packet_t;
-*/
-
-/* valid ip_protocol for UDP management */
-#define UDPMGMT_UDP_PROTOCOL 0x11
-
-
-typedef struct {
-	unsigned char	status		PACKED;
-	unsigned char	data_avail	PACKED;
-	unsigned short	real_length	PACKED;
-	unsigned short	time_stamp	PACKED;
-	unsigned char	data[1]		PACKED;
-} trace_pkt_t;
-
-typedef struct {
-	unsigned char	error_flag	PACKED;
-	unsigned short	time_stamp	PACKED;
-	unsigned char	reserved[13]	PACKED;
-} api_rx_hdr_t;
-
-typedef struct {
-        api_rx_hdr_t	api_rx_hdr      PACKED;
-        void *   	data    	PACKED;
-} api_rx_element_t;
-
-typedef struct {
-	unsigned char 	attr		PACKED;
-	unsigned char  	reserved[15]	PACKED;
-} api_tx_hdr_t;
-
-typedef struct {
-	api_tx_hdr_t 	api_tx_hdr	PACKED;
-	void *		data		PACKED;
-} api_tx_element_t;
-
-/* ----------------------------------------------------------------------------
- *   Constants for the SET_FT1_CONFIGURATION/READ_FT1_CONFIGURATION command
- * --------------------------------------------------------------------------*/
-
-/* the FT1 configuration structure */
-typedef struct {
-	unsigned short framing_mode;
-	unsigned short encoding_mode;
-	unsigned short line_build_out;
-	unsigned short channel_base;
-	unsigned short baud_rate_kbps;					/* the baud rate (in kbps) */	
-	unsigned short clock_mode;
-} ft1_config_t;
-
-/* settings for the 'framing_mode' */
-#define ESF_FRAMING 	0x00	/* ESF framing */
-#define D4_FRAMING  	0x01	/* D4 framing */
-
-/* settings for the 'encoding_mode' */
-#define B8ZS_ENCODING 	0x00	/* B8ZS encoding */
-#define AMI_ENCODING	0x01	/* AMI encoding */
-
-/* settings for the 'line_build_out' */
-#define LN_BLD_CSU_0dB_DSX1_0_to_133	0x00	/* set build out to CSU (0db) or DSX-1 (0-133ft) */
-#define LN_BLD_DSX1_133_to_266		0x01	/* set build out DSX-1 (133-266ft) */
-#define LN_BLD_DSX1_266_to_399		0x02	/* set build out DSX-1 (266-399ft) */
-#define LN_BLD_DSX1_399_to_533		0x03	/* set build out DSX-1 (399-533ft) */
-#define LN_BLD_DSX1_533_to_655		0x04	/* set build out DSX-1 (533-655ft) */
-#define LN_BLD_CSU_NEG_7dB		0x05	/* set build out to CSU (-7.5db) */
-#define LN_BLD_CSU_NEG_15dB		0x06	/* set build out to CSU (-15db) */
-#define LN_BLD_CSU_NEG_22dB		0x07	/* set build out to CSU (-22.5db) */
-
-/* settings for the 'channel_base' */
-#define MIN_CHANNEL_BASE_VALUE		1		/* the minimum permitted channel base value */
-#define MAX_CHANNEL_BASE_VALUE		24		/* the maximum permitted channel base value */
-
-/* settings for the 'baud_rate_kbps' */
-#define MIN_BAUD_RATE_KBPS		0		/* the minimum permitted baud rate (kbps) */
-#define MAX_BAUD_RATE_KBPS 		1536	/* the maximum permitted baud rate (kbps) */
-#define BAUD_RATE_FT1_AUTO_CONFIG	0xFFFF /* the baud rate used to trigger an automatic FT1 configuration */
-
-/* settings for the 'clock_mode' */
-#define CLOCK_MODE_NORMAL		0x00	/* clock mode set to normal (slave) */
-#define CLOCK_MODE_MASTER		0x01	/* clock mode set to master */
-
-
-#define BAUD_RATE_FT1_AUTO_CONFIG   	0xFFFF
-#define AUTO_FT1_CONFIG_NOT_COMPLETE	0x08
-#define AUTO_FT1_CFG_FAIL_OP_MODE	0x0C
-#define AUTO_FT1_CFG_FAIL_INVALID_LINE 	0x0D
-
- 
-#ifdef		_MSC_
-#  pragma	pack()
-#endif
-#endif	/* _SDLA_CHDLC_H */
diff --git a/include/linux/sdla_ppp.h b/include/linux/sdla_ppp.h
deleted file mode 100644
index 6f39231..0000000
--- a/include/linux/sdla_ppp.h
+++ /dev/null
@@ -1,575 +0,0 @@
-/*****************************************************************************
-* sdla_ppp.h	Sangoma PPP firmware API definitions.
-*
-* Author:	Nenad Corbic	<ncorbic@sangoma.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.
-* ============================================================================
-* Feb 24, 2000  Nenad Corbic    v2.1.2
-* Jan 06, 1997	Gene Kozin	v2.0
-* Apr 11, 1996	Gene Kozin	Initial version.
-*****************************************************************************/
-#ifndef	_SDLA_PPP_H
-#define	_SDLA_PPP_H
-
-/*----------------------------------------------------------------------------
- * Notes:
- * ------
- * 1. All structures defined in this file are byte-alined.  
- *
- *	Compiler	Platform
- *	--------	--------
- *	GNU C		Linux		
- */
-
-#ifndef	PACKED
-#    define	PACKED	__attribute__((packed))
-#endif	/* PACKED */
-
-/* Adapter memory layout and important constants */
-#define	PPP508_MB_VECT	0xE000	/* mailbox window vector */
-#define	PPP508_MB_OFFS	0		/* mailbox offset */
-#define	PPP508_FLG_OFFS	0x1000	/* status flags offset */
-#define	PPP508_BUF_OFFS	0x1100	/* buffer info block offset */
-#define PPP514_MB_OFFS  0xE000  /* mailbox offset */
-#define PPP514_FLG_OFFS 0xF000  /* status flags offset */
-#define PPP514_BUF_OFFS 0xF100  /* buffer info block offset */
-
-#define PPP_MAX_DATA	1008	/* command block data buffer length */
-
-/****** Data Structures *****************************************************/
-
-/*----------------------------------------------------------------------------
- * PPP Command Block.
- */
-typedef struct ppp_cmd{
-	unsigned char  command	PACKED;	/* command code */
-	unsigned short length	PACKED;	/* length of data buffer */
-	unsigned char  result	PACKED;	/* return code */
-	unsigned char  rsrv[11]	PACKED;	/* reserved for future use */
-} ppp_cmd_t;
-
-typedef struct cblock{
-	unsigned char  opp_flag	PACKED;
-	unsigned char  command	PACKED;	/* command code */
-	unsigned short length	PACKED;	/* length of data buffer */
-	unsigned char  result	PACKED;	/* return code */
-	unsigned char  rsrv[11]	PACKED;	/* reserved for future use */
-} cblock_t;
-
-typedef struct ppp_udp_pkt{
-	ip_pkt_t 	ip_pkt	PACKED;
-	udp_pkt_t	udp_pkt	PACKED;
-	wp_mgmt_t	wp_mgmt PACKED;
-	cblock_t	cblock  PACKED;
-	unsigned char   data[MAX_LGTH_UDP_MGNT_PKT] PACKED;
-} ppp_udp_pkt_t;	
-
-typedef struct {
-	unsigned char	status		PACKED;
-	unsigned char	data_avail	PACKED;
-	unsigned short	real_length	PACKED;
-	unsigned short	time_stamp	PACKED;
-	unsigned char	data[1]		PACKED;
-} trace_pkt_t;
-
-
-typedef struct {
-	unsigned char 	opp_flag	PACKED;
-	unsigned char	trace_type	PACKED;
-	unsigned short 	trace_length	PACKED;
-	unsigned short 	trace_data_ptr	PACKED;
-	unsigned short  trace_time_stamp PACKED;
-} trace_element_t;
-
-/* 'command' field defines */
-#define PPP_READ_CODE_VERSION	0x10	/* configuration commands */
-#define PPP_SET_CONFIG		0x05
-#define PPP_READ_CONFIG		0x06
-#define	PPP_SET_INTR_FLAGS	0x20
-#define	PPP_READ_INTR_FLAGS	0x21
-#define	PPP_SET_INBOUND_AUTH	0x30
-#define	PPP_SET_OUTBOUND_AUTH	0x31
-#define	PPP_GET_CONNECTION_INFO	0x32
-
-#define PPP_COMM_ENABLE		0x03	/* operational commands */
-#define PPP_COMM_DISABLE	0x04
-#define	PPP_SEND_SIGN_FRAME	0x23
-#define	PPP_READ_SIGN_RESPONSE	0x24
-#define	PPP_DATALINE_MONITOR	0x33
-
-#define PPP_READ_STATISTICS	0x07	/* statistics commands */
-#define PPP_FLUSH_STATISTICS	0x08
-#define PPP_READ_ERROR_STATS	0x09
-#define PPP_FLUSH_ERROR_STATS	0x0A
-#define PPP_READ_PACKET_STATS	0x12
-#define PPP_FLUSH_PACKET_STATS	0x13
-#define PPP_READ_LCP_STATS	0x14
-#define PPP_FLUSH_LCP_STATS	0x15
-#define PPP_READ_LPBK_STATS	0x16
-#define PPP_FLUSH_LPBK_STATS	0x17
-#define PPP_READ_IPCP_STATS	0x18
-#define PPP_FLUSH_IPCP_STATS	0x19
-#define PPP_READ_IPXCP_STATS	0x1A
-#define PPP_FLUSH_IPXCP_STATS	0x1B
-#define PPP_READ_PAP_STATS	0x1C
-#define PPP_FLUSH_PAP_STATS	0x1D
-#define PPP_READ_CHAP_STATS	0x1E
-#define PPP_FLUSH_CHAP_STATS	0x1F
-
-/* 'result' field defines */
-#define PPPRES_OK		0x00	/* command executed successfully */
-#define	PPPRES_INVALID_STATE	0x09	/* invalid command in this context */
-
-/*----------------------------------------------------------------------------
- * PPP Mailbox.
- *	This structure is located at offset PPP???_MB_OFFS into PPP???_MB_VECT
- */
-typedef struct ppp_mbox
-{
-	unsigned char flag	PACKED;	/* 00h: command execution flag */
-	ppp_cmd_t     cmd	PACKED; /* 01h: command block */
-	unsigned char data[1]	PACKED;	/* 10h: variable length data buffer */
-} ppp_mbox_t;
-
-/*----------------------------------------------------------------------------
- * PPP Status Flags.
- *	This structure is located at offset PPP???_FLG_OFFS into
- *	PPP???_MB_VECT.
- */
-typedef struct	ppp_flags
-{
-	unsigned char iflag		PACKED;	/* 00: interrupt flag */
-	unsigned char imask		PACKED;	/* 01: interrupt mask */
-	unsigned char resrv		PACKED;
-	unsigned char mstatus		PACKED;	/* 03: modem status */
-	unsigned char lcp_state		PACKED; /* 04: LCP state */
-	unsigned char ppp_phase		PACKED;	/* 05: PPP phase */
-	unsigned char ip_state		PACKED; /* 06: IPCP state */
-	unsigned char ipx_state		PACKED; /* 07: IPXCP state */
-	unsigned char pap_state		PACKED; /* 08: PAP state */
-	unsigned char chap_state	PACKED; /* 09: CHAP state */
-	unsigned short disc_cause	PACKED;	/* 0A: disconnection cause */
-} ppp_flags_t;
-
-/* 'iflag' defines */
-#define	PPP_INTR_RXRDY		0x01	/* Rx ready */
-#define	PPP_INTR_TXRDY		0x02	/* Tx ready */
-#define	PPP_INTR_MODEM		0x04	/* modem status change (DCD, CTS) */
-#define	PPP_INTR_CMD		0x08	/* interface command completed */
-#define	PPP_INTR_DISC		0x10	/* data link disconnected */
-#define	PPP_INTR_OPEN		0x20	/* data link open */
-#define	PPP_INTR_DROP_DTR	0x40	/* DTR drop timeout expired */
-#define PPP_INTR_TIMER          0x80    /* timer interrupt */
-
-
-/* 'mstatus' defines */
-#define	PPP_MDM_DCD		0x08	/* mdm_status: DCD */
-#define	PPP_MDM_CTS		0x20	/* mdm_status: CTS */
-
-/* 'disc_cause' defines */
-#define PPP_LOCAL_TERMINATION   0x0001	/* Local Request by PPP termination phase */
-#define PPP_DCD_CTS_DROP        0x0002  /* DCD and/or CTS dropped. Link down */
-#define PPP_REMOTE_TERMINATION	0x0800	/* Remote Request by PPP termination phase */
-
-/* 'misc_config_bits' defines */
-#define DONT_RE_TX_ABORTED_I_FRAMES 	0x01
-#define TX_FRM_BYTE_COUNT_STATS         0x02
-#define RX_FRM_BYTE_COUNT_STATS         0x04
-#define TIME_STAMP_IN_RX_FRAMES         0x08
-#define NON_STD_ADPTR_FREQ              0x10
-#define INTERFACE_LEVEL_RS232           0x20
-#define AUTO_LINK_RECOVERY              0x100
-#define DONT_TERMINATE_LNK_MAX_CONFIG   0x200                    
-
-/* 'authentication options' defines */
-#define NO_AUTHENTICATION	0x00
-#define INBOUND_AUTH		0x80
-#define PAP_AUTH		0x01
-#define CHAP_AUTH		0x02		
-
-/* 'ip options' defines */
-#define L_AND_R_IP_NO_ASSIG	0x00
-#define L_IP_LOCAL_ASSIG    	0x01
-#define L_IP_REMOTE_ASSIG   	0x02
-#define R_IP_LOCAL_ASSIG        0x04
-#define R_IP_REMOTE_ASSIG       0x08
-#define ENABLE_IP		0x80
-
-/* 'ipx options' defines */
-#define ROUTING_PROT_DEFAULT    0x20
-#define ENABLE_IPX		0x80
-#define DISABLE_IPX		0x00
-
-/*----------------------------------------------------------------------------
- * PPP Buffer Info.
- *	This structure is located at offset PPP508_BUF_OFFS into
- *	PPP508_MB_VECT.
- */
-typedef struct	ppp508_buf_info
-{
-	unsigned short txb_num	PACKED;	/* 00: number of transmit buffers */
-	unsigned long  txb_ptr	PACKED;	/* 02: pointer to the buffer ctl. */
-	unsigned long  txb_nxt  PACKED;
-	unsigned char  rsrv1[22] PACKED;
-	unsigned short rxb_num	PACKED;	/* 20: number of receive buffers */
-	unsigned long  rxb_ptr	PACKED;	/* 22: pointer to the buffer ctl. */
-	unsigned long  rxb1_ptr	PACKED;	/* 26: pointer to the first buf.ctl. */
-	unsigned long  rxb_base	PACKED;	/* 2A: pointer to the buffer base */
-	unsigned char  rsrv2[2]	PACKED;
-	unsigned long  rxb_end	PACKED;	/* 30: pointer to the buffer end */
-} ppp508_buf_info_t;
-
-/*----------------------------------------------------------------------------
- * Transmit/Receive Buffer Control Block.
- */
-typedef struct	ppp_buf_ctl
-{
-	unsigned char  flag		PACKED;	/* 00: 'buffer ready' flag */
-	unsigned short length		PACKED;	/* 01: length of data */
-	unsigned char  reserved1[1]	PACKED;	/* 03: */
-	unsigned char  proto		PACKED;	/* 04: protocol */
-	unsigned short timestamp	PACKED;	/* 05: time stamp (Rx only) */
-	unsigned char  reserved2[5]	PACKED;	/* 07: */
-	union
-	{
-		unsigned short o_p[2];	/* 1C: buffer offset & page (S502) */
-		unsigned long  ptr;	/* 1C: buffer pointer (S508) */
-	} buf				PACKED;
-} ppp_buf_ctl_t;
-
-/*----------------------------------------------------------------------------
- * S508 Adapter Configuration Block (passed to the PPP_SET_CONFIG command).
- */
-typedef struct	ppp508_conf
-{
-	unsigned long  line_speed	PACKED;	/* 00: baud rate, bps */
-	unsigned short txbuf_percent	PACKED;	/* 04: % of Tx buffer */
-	unsigned short conf_flags	PACKED;	/* 06: configuration bits */
-	unsigned short mtu_local	PACKED;	/* 08: local MTU */
-	unsigned short mtu_remote	PACKED;	/* 0A: remote MTU */
-	unsigned short restart_tmr	PACKED;	/* 0C: restart timer */
-	unsigned short auth_rsrt_tmr	PACKED;	/* 0E: authentication timer */
-	unsigned short auth_wait_tmr	PACKED;	/* 10: authentication timer */
-	unsigned short mdm_fail_tmr	PACKED;	/* 12: modem failure timer */
-	unsigned short dtr_drop_tmr	PACKED;	/* 14: DTR drop timer */
-	unsigned short connect_tmout	PACKED;	/* 16: connection timeout */
-	unsigned short conf_retry	PACKED;	/* 18: max. retry */
-	unsigned short term_retry	PACKED;	/* 1A: max. retry */
-	unsigned short fail_retry	PACKED;	/* 1C: max. retry */
-	unsigned short auth_retry	PACKED;	/* 1E: max. retry */
-	unsigned char  auth_options	PACKED;	/* 20: authentication opt. */
-	unsigned char  ip_options	PACKED;	/* 21: IP options */
-	unsigned long  ip_local		PACKED;	/* 22: local IP address */
-	unsigned long  ip_remote	PACKED;	/* 26: remote IP address */
-	unsigned char  ipx_options	PACKED;	/* 2A: IPX options */
-	unsigned char  ipx_netno[4]	PACKED;	/* 2B: IPX net number */
-	unsigned char  ipx_local[6]	PACKED;	/* 2F: local IPX node number*/
-	unsigned char  ipx_remote[6]	PACKED;	/* 35: remote IPX node num.*/
-	unsigned char  ipx_router[48]	PACKED;	/* 3B: IPX router name*/
-	unsigned long  alt_cpu_clock	PACKED;	/* 6B:  */
-} ppp508_conf_t;
-
-/*----------------------------------------------------------------------------
- * S508 Adapter Read Connection Information Block 
- *    Returned by the PPP_GET_CONNECTION_INFO command
- */
-typedef struct	ppp508_connect_info
-{
-	unsigned short 	mru		PACKED;	/* 00-01 Remote Max Rec' Unit */
-	unsigned char  	ip_options 	PACKED; /* 02: Negotiated ip options  */
-	unsigned long  	ip_local	PACKED;	/* 03-06: local IP address    */
-	unsigned long  	ip_remote	PACKED;	/* 07-0A: remote IP address   */
-	unsigned char	ipx_options	PACKED; /* 0B: Negotiated ipx options */
-	unsigned char  	ipx_netno[4]	PACKED;	/* 0C-0F: IPX net number      */
-	unsigned char  	ipx_local[6]	PACKED;	/* 10-1F: local IPX node #    */
-	unsigned char  	ipx_remote[6]	PACKED;	/* 16-1B: remote IPX node #   */
-	unsigned char  	ipx_router[48]	PACKED;	/* 1C-4B: IPX router name     */
-	unsigned char	auth_status	PACKED; /* 4C: Authentication Status  */
-	unsigned char 	inbd_auth_peerID[1] PACKED; /* 4D: variable length inbound authenticated peer ID */
-} ppp508_connect_info_t;
-
-/* 'line_speed' field */
-#define	PPP_BITRATE_1200	0x01
-#define	PPP_BITRATE_2400	0x02
-#define	PPP_BITRATE_4800	0x03
-#define	PPP_BITRATE_9600	0x04
-#define	PPP_BITRATE_19200	0x05
-#define	PPP_BITRATE_38400	0x06
-#define	PPP_BITRATE_45000	0x07
-#define	PPP_BITRATE_56000	0x08
-#define	PPP_BITRATE_64000	0x09
-#define	PPP_BITRATE_74000	0x0A
-#define	PPP_BITRATE_112000	0x0B
-#define	PPP_BITRATE_128000	0x0C
-#define	PPP_BITRATE_156000	0x0D
-
-/* Defines for the 'conf_flags' field */
-#define	PPP_IGNORE_TX_ABORT	0x01	/* don't re-transmit aborted frames */
-#define	PPP_ENABLE_TX_STATS	0x02	/* enable Tx statistics */
-#define	PPP_ENABLE_RX_STATS	0x04	/* enable Rx statistics */
-#define	PPP_ENABLE_TIMESTAMP	0x08	/* enable timestamp */
-
-/* 'ip_options' defines */
-#define	PPP_LOCAL_IP_LOCAL	0x01
-#define	PPP_LOCAL_IP_REMOTE	0x02
-#define	PPP_REMOTE_IP_LOCAL	0x04
-#define	PPP_REMOTE_IP_REMOTE	0x08
-
-/* 'ipx_options' defines */
-#define	PPP_REMOTE_IPX_NETNO	0x01
-#define	PPP_REMOTE_IPX_LOCAL	0x02
-#define	PPP_REMOTE_IPX_REMOTE	0x04
-#define	PPP_IPX_ROUTE_RIP_SAP	0x08
-#define	PPP_IPX_ROUTE_NLSP	0x10
-#define	PPP_IPX_ROUTE_DEFAULT	0x20
-#define	PPP_IPX_CONF_COMPLETE	0x40
-#define	PPP_IPX_ENABLE		0x80
-
-/*----------------------------------------------------------------------------
- * S508 Adapter Configuration Block (returned by the PPP_READ_CONFIG command).
- */
-typedef struct	ppp508_get_conf
-{
-	unsigned long  bps	PACKED;	/* 00: baud rate, bps */
-	ppp508_conf_t  conf	PACKED;	/* 04: requested config. */
-	unsigned short txb_num	PACKED;	/* 6F: number of Tx buffers */
-	unsigned short rxb_num	PACKED;	/* 71: number of Rx buffers */
-} ppp508_get_conf_t;
-
-/*----------------------------------------------------------------------------
- * S508 Operational Statistics (returned by the PPP_READ_STATISTIC command).
- */
-typedef struct ppp508_stats
-{
-	unsigned short reserved1	PACKED;	/* 00: */
-	unsigned short rx_bad_len	PACKED;	/* 02: */
-	unsigned short reserved2	PACKED;	/* 04: */
-	unsigned long  tx_frames	PACKED;	/* 06: */
-	unsigned long  tx_bytes	PACKED;	/* 0A: */
-	unsigned long  rx_frames	PACKED;	/* 0E: */
-	unsigned long  rx_bytes	PACKED;	/* 12: */
-} ppp508_stats_t;
-
-/*----------------------------------------------------------------------------
- * Adapter Error Statistics (returned by the PPP_READ_ERROR_STATS command).
- */
-typedef struct	ppp_err_stats
-{
-	unsigned char	 rx_overrun	PACKED;	/* 00: Rx overrun errors */
-	unsigned char	 rx_bad_crc	PACKED;	/* 01: Rx CRC errors */
-	unsigned char	 rx_abort	PACKED;	/* 02: Rx aborted frames */
-	unsigned char	 rx_lost	PACKED;	/* 03: Rx frames lost */
-	unsigned char	 tx_abort	PACKED;	/* 04: Tx aborted frames */
-	unsigned char	 tx_underrun	PACKED;	/* 05: Tx underrun errors */
-	unsigned char	 tx_missed_intr	PACKED;	/* 06: Tx underruns missed */
-	unsigned char	 reserved	PACKED;	/* 07: Tx underruns missed */
-	unsigned char	 dcd_trans	PACKED;	/* 08: DCD transitions */
-	unsigned char	 cts_trans	PACKED;	/* 09: CTS transitions */
-} ppp_err_stats_t;
-
-/*----------------------------------------------------------------------------
- * Packet Statistics (returned by the PPP_READ_PACKET_STATS command).
- */
-typedef struct	ppp_pkt_stats
-{
-	unsigned short rx_bad_header	PACKED;	/* 00: */
-	unsigned short rx_prot_unknwn	PACKED;	/* 02: */
-	unsigned short rx_too_large	PACKED;	/* 04: */
-	unsigned short rx_lcp		PACKED;	/* 06: */
-	unsigned short tx_lcp		PACKED;	/* 08: */
-	unsigned short rx_ipcp		PACKED;	/* 0A: */
-	unsigned short tx_ipcp		PACKED;	/* 0C: */
-	unsigned short rx_ipxcp		PACKED;	/* 0E: */
-	unsigned short tx_ipxcp		PACKED;	/* 10: */
-	unsigned short rx_pap		PACKED;	/* 12: */
-	unsigned short tx_pap		PACKED;	/* 14: */
-	unsigned short rx_chap		PACKED;	/* 16: */
-	unsigned short tx_chap		PACKED;	/* 18: */
-	unsigned short rx_lqr		PACKED;	/* 1A: */
-	unsigned short tx_lqr		PACKED;	/* 1C: */
-	unsigned short rx_ip		PACKED;	/* 1E: */
-	unsigned short tx_ip		PACKED;	/* 20: */
-	unsigned short rx_ipx		PACKED;	/* 22: */
-	unsigned short tx_ipx		PACKED;	/* 24: */
-} ppp_pkt_stats_t;
-
-/*----------------------------------------------------------------------------
- * LCP Statistics (returned by the PPP_READ_LCP_STATS command).
- */
-typedef struct	ppp_lcp_stats
-{
-	unsigned short rx_unknown	PACKED;	/* 00: unknown LCP type */
-	unsigned short rx_conf_rqst	PACKED;	/* 02: Configure-Request */
-	unsigned short rx_conf_ack	PACKED;	/* 04: Configure-Ack */
-	unsigned short rx_conf_nak	PACKED;	/* 06: Configure-Nak */
-	unsigned short rx_conf_rej	PACKED;	/* 08: Configure-Reject */
-	unsigned short rx_term_rqst	PACKED;	/* 0A: Terminate-Request */
-	unsigned short rx_term_ack	PACKED;	/* 0C: Terminate-Ack */
-	unsigned short rx_code_rej	PACKED;	/* 0E: Code-Reject */
-	unsigned short rx_proto_rej	PACKED;	/* 10: Protocol-Reject */
-	unsigned short rx_echo_rqst	PACKED;	/* 12: Echo-Request */
-	unsigned short rx_echo_reply	PACKED;	/* 14: Echo-Reply */
-	unsigned short rx_disc_rqst	PACKED;	/* 16: Discard-Request */
-	unsigned short tx_conf_rqst	PACKED;	/* 18: Configure-Request */
-	unsigned short tx_conf_ack	PACKED;	/* 1A: Configure-Ack */
-	unsigned short tx_conf_nak	PACKED;	/* 1C: Configure-Nak */
-	unsigned short tx_conf_rej	PACKED;	/* 1E: Configure-Reject */
-	unsigned short tx_term_rqst	PACKED;	/* 20: Terminate-Request */
-	unsigned short tx_term_ack	PACKED;	/* 22: Terminate-Ack */
-	unsigned short tx_code_rej	PACKED;	/* 24: Code-Reject */
-	unsigned short tx_proto_rej	PACKED;	/* 26: Protocol-Reject */
-	unsigned short tx_echo_rqst	PACKED;	/* 28: Echo-Request */
-	unsigned short tx_echo_reply	PACKED;	/* 2A: Echo-Reply */
-	unsigned short tx_disc_rqst	PACKED;	/* 2E: Discard-Request */
-	unsigned short rx_too_large	PACKED;	/* 30: packets too large */
-	unsigned short rx_ack_inval	PACKED;	/* 32: invalid Conf-Ack */
-	unsigned short rx_rej_inval	PACKED;	/* 34: invalid Conf-Reject */
-	unsigned short rx_rej_badid	PACKED;	/* 36: Conf-Reject w/bad ID */
-} ppp_lcp_stats_t;
-
-/*----------------------------------------------------------------------------
- * Loopback Error Statistics (returned by the PPP_READ_LPBK_STATS command).
- */
-typedef struct	ppp_lpbk_stats
-{
-	unsigned short conf_magic	PACKED;	/* 00:  */
-	unsigned short loc_echo_rqst	PACKED;	/* 02:  */
-	unsigned short rem_echo_rqst	PACKED;	/* 04:  */
-	unsigned short loc_echo_reply	PACKED;	/* 06:  */
-	unsigned short rem_echo_reply	PACKED;	/* 08:  */
-	unsigned short loc_disc_rqst	PACKED;	/* 0A:  */
-	unsigned short rem_disc_rqst	PACKED;	/* 0C:  */
-	unsigned short echo_tx_collsn	PACKED;	/* 0E:  */
-	unsigned short echo_rx_collsn	PACKED;	/* 10:  */
-} ppp_lpbk_stats_t;
-
-/*----------------------------------------------------------------------------
- * Protocol Statistics (returned by the PPP_READ_IPCP_STATS and
- * PPP_READ_IPXCP_STATS commands).
- */
-typedef struct	ppp_prot_stats
-{
-	unsigned short rx_unknown	PACKED;	/* 00: unknown type */
-	unsigned short rx_conf_rqst	PACKED;	/* 02: Configure-Request */
-	unsigned short rx_conf_ack	PACKED;	/* 04: Configure-Ack */
-	unsigned short rx_conf_nak	PACKED;	/* 06: Configure-Nak */
-	unsigned short rx_conf_rej	PACKED;	/* 08: Configure-Reject */
-	unsigned short rx_term_rqst	PACKED;	/* 0A: Terminate-Request */
-	unsigned short rx_term_ack	PACKED;	/* 0C: Terminate-Ack */
-	unsigned short rx_code_rej	PACKED;	/* 0E: Code-Reject */
-	unsigned short reserved		PACKED;	/* 10: */
-	unsigned short tx_conf_rqst	PACKED;	/* 12: Configure-Request */
-	unsigned short tx_conf_ack	PACKED;	/* 14: Configure-Ack */
-	unsigned short tx_conf_nak	PACKED;	/* 16: Configure-Nak */
-	unsigned short tx_conf_rej	PACKED;	/* 18: Configure-Reject */
-	unsigned short tx_term_rqst	PACKED;	/* 1A: Terminate-Request */
-	unsigned short tx_term_ack	PACKED;	/* 1C: Terminate-Ack */
-	unsigned short tx_code_rej	PACKED;	/* 1E: Code-Reject */
-	unsigned short rx_too_large	PACKED;	/* 20: packets too large */
-	unsigned short rx_ack_inval	PACKED;	/* 22: invalid Conf-Ack */
-	unsigned short rx_rej_inval	PACKED;	/* 24: invalid Conf-Reject */
-	unsigned short rx_rej_badid	PACKED;	/* 26: Conf-Reject w/bad ID */
-} ppp_prot_stats_t;
-
-/*----------------------------------------------------------------------------
- * PAP Statistics (returned by the PPP_READ_PAP_STATS command).
- */
-typedef struct	ppp_pap_stats
-{
-	unsigned short rx_unknown	PACKED;	/* 00: unknown type */
-	unsigned short rx_auth_rqst	PACKED;	/* 02: Authenticate-Request */
-	unsigned short rx_auth_ack	PACKED;	/* 04: Authenticate-Ack */
-	unsigned short rx_auth_nak	PACKED;	/* 06: Authenticate-Nak */
-	unsigned short reserved		PACKED;	/* 08: */
-	unsigned short tx_auth_rqst	PACKED;	/* 0A: Authenticate-Request */
-	unsigned short tx_auth_ack	PACKED;	/* 0C: Authenticate-Ack */
-	unsigned short tx_auth_nak	PACKED;	/* 0E: Authenticate-Nak */
-	unsigned short rx_too_large	PACKED;	/* 10: packets too large */
-	unsigned short rx_bad_peerid	PACKED;	/* 12: invalid peer ID */
-	unsigned short rx_bad_passwd	PACKED;	/* 14: invalid password */
-} ppp_pap_stats_t;
-
-/*----------------------------------------------------------------------------
- * CHAP Statistics (returned by the PPP_READ_CHAP_STATS command).
- */
-typedef struct	ppp_chap_stats
-{
-	unsigned short rx_unknown	PACKED;	/* 00: unknown type */
-	unsigned short rx_challenge	PACKED;	/* 02: Authenticate-Request */
-	unsigned short rx_response	PACKED;	/* 04: Authenticate-Ack */
-	unsigned short rx_success	PACKED;	/* 06: Authenticate-Nak */
-	unsigned short rx_failure	PACKED;	/* 08: Authenticate-Nak */
-	unsigned short reserved		PACKED;	/* 0A: */
-	unsigned short tx_challenge	PACKED;	/* 0C: Authenticate-Request */
-	unsigned short tx_response	PACKED;	/* 0E: Authenticate-Ack */
-	unsigned short tx_success	PACKED;	/* 10: Authenticate-Nak */
-	unsigned short tx_failure	PACKED;	/* 12: Authenticate-Nak */
-	unsigned short rx_too_large	PACKED;	/* 14: packets too large */
-	unsigned short rx_bad_peerid	PACKED;	/* 16: invalid peer ID */
-	unsigned short rx_bad_passwd	PACKED;	/* 18: invalid password */
-	unsigned short rx_bad_md5	PACKED;	/* 1A: invalid MD5 format */
-	unsigned short rx_bad_resp	PACKED;	/* 1C: invalid response */
-} ppp_chap_stats_t;
-
-/*----------------------------------------------------------------------------
- * Connection Information (returned by the PPP_GET_CONNECTION_INFO command).
- */
-typedef struct	ppp_conn_info
-{
-	unsigned short remote_mru	PACKED;	/* 00:  */
-	unsigned char  ip_options	PACKED;	/* 02:  */
-	unsigned char  ip_local[4]	PACKED;	/* 03:  */
-	unsigned char  ip_remote[4]	PACKED;	/* 07:  */
-	unsigned char  ipx_options	PACKED;	/* 0B:  */
-	unsigned char  ipx_network[4]	PACKED;	/* 0C:  */
-	unsigned char  ipx_local[6]	PACKED;	/* 10:  */
-	unsigned char  ipx_remote[6]	PACKED;	/* 16:  */
-	unsigned char  ipx_router[48]	PACKED;	/* 1C:  */
-	unsigned char  auth_status	PACKED;	/* 4C:  */
-	unsigned char  peer_id[0]	PACKED;	/* 4D:  */
-} ppp_conn_info_t;
-
-/* Data structure for SET_TRIGGER_INTR command
- */
-
-typedef struct ppp_intr_info{
-	unsigned char  i_enable		PACKED; /* 0 Interrupt enable bits */
-	unsigned char  irq              PACKED; /* 1 Irq number */
-	unsigned short timer_len        PACKED; /* 2 Timer delay */
-} ppp_intr_info_t;
-
-
-#define FT1_MONITOR_STATUS_CTRL                         0x80
-#define SET_FT1_MODE                                    0x81
-
-
-
-/* Special UDP drivers management commands */
-#define PPIPE_ENABLE_TRACING                            0x20
-#define PPIPE_DISABLE_TRACING                           0x21
-#define PPIPE_GET_TRACE_INFO                            0x22
-#define PPIPE_GET_IBA_DATA                              0x23
-#define PPIPE_KILL_BOARD     				0x24
-#define PPIPE_FT1_READ_STATUS                           0x25
-#define PPIPE_DRIVER_STAT_IFSEND                        0x26
-#define PPIPE_DRIVER_STAT_INTR                          0x27
-#define PPIPE_DRIVER_STAT_GEN                           0x28
-#define PPIPE_FLUSH_DRIVER_STATS                        0x29
-#define PPIPE_ROUTER_UP_TIME                            0x30
-
-#define DISABLE_TRACING 				0x00
-#define TRACE_SIGNALLING_FRAMES				0x01
-#define TRACE_DATA_FRAMES				0x02
-
-
-
-#ifdef		_MSC_
-#  pragma	pack()
-#endif
-#endif	/* _SDLA_PPP_H */
diff --git a/include/linux/sdla_x25.h b/include/linux/sdla_x25.h
deleted file mode 100644
index 57db980..0000000
--- a/include/linux/sdla_x25.h
+++ /dev/null
@@ -1,772 +0,0 @@
-/*****************************************************************************
-* sdla_x25.h	Sangoma X.25 firmware API definitions.
-*
-* Author:	Nenad Corbic	<ncorbic@sangoma.com>
-*
-* Copyright:	(c) 1995-2000 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.
-* ============================================================================
-* Feb 28, 2000  Nenad Corbic    Updated for socket based x25api
-* Dec 13, 1996	Gene Kozin	Initial version
-*****************************************************************************/
-#ifndef	_SDLA_X25_H
-#define	_SDLA_X25_H
-
-/*----------------------------------------------------------------------------
- * Notes:
- * ------
- * 1. All structures defined in this file are byte-alined.  
- *	Compiler	Platform	
- *	--------	--------
- *	GNU C		Linux
- *
- */
-
-#ifndef	PACKED
-#	define	PACKED	__attribute__((packed))
-#endif	/* PACKED */
-
-/******	CONSTANTS DEFINITIONS ***********************************************/
-
-#define	X25_MAX_CHAN	255	/* max number of open X.25 circuits */
-#define	X25_MAX_DATA	1024	/* max length of X.25 data buffer */
-/*
- * X.25 shared memory layout.
- */
-#define	X25_MBOX_OFFS	0x16B0	/* general mailbox block */
-#define	X25_RXMBOX_OFFS	0x1AD0	/* receive mailbox */
-#define	X25_STATUS_OFFS	0x1EF0	/* X.25 status structure */
-#define X25_MB_VECTOR	0xE000	/* S514 mailbox window vecotr */
-#define X25_MISC_HDLC_BITS 0x1F00 /*X.25 miscallaneous HDLC bits */
-
-/* code levels */
-#define HDLC_LEVEL 0x01
-#define X25_LEVEL  0x02
-#define X25_AND_HDLC_LEVEL 0x03
-#define DO_HDLC_LEVEL_ERROR_CHECKING 0x04
-
-/****** DATA STRUCTURES *****************************************************/
-
-/*----------------------------------------------------------------------------
- * X.25 Command Block.
- */
-typedef struct X25Cmd
-{
-	unsigned char command	PACKED;	/* command code */
-	unsigned short length	PACKED;	/* transfer data length */
-	unsigned char result	PACKED;	/* return code */
-	unsigned char pf	PACKED;	/* P/F bit */
-	unsigned short lcn	PACKED;	/* logical channel */
-	unsigned char qdm	PACKED;	/* Q/D/M bits */
-	unsigned char cause	PACKED;	/* cause field */
-	unsigned char diagn	PACKED;	/* diagnostics */
-	unsigned char pktType	PACKED;	/* packet type */
-	unsigned char resrv[4]	PACKED;	/* reserved */
-} TX25Cmd;
-
-/*
- * Defines for the 'command' field.
- */
-/*----- General commands --------------*/
-#define X25_SET_GLOBAL_VARS	0x0B   	/* set global variables */ 
-#define X25_READ_MODEM_STATUS	0x0C 	/* read modem status */
-#define X25_READ_CODE_VERSION	0x15	/* read firmware version number */
-#define X25_TRACE_CONFIGURE	0x14	/* configure trace facility */
-#define X25_READ_TRACE_DATA	0x16	/* read trace data */
-#define	X25_SET_INTERRUPT_MODE	0x17	/* set interrupt generation mode */
-#define	X25_READ_INTERRUPT_MODE	0x18	/* read interrupt generation mode */
-/*----- HDLC-level commands -----------*/
-#define X25_HDLC_LINK_CONFIGURE	0x01	/* configure HDLC link level */   
-#define X25_HDLC_LINK_OPEN	0x02	/* open HDLC link */         	
-#define X25_HDLC_LINK_CLOSE	0x03	/* close HDLC link */
-#define X25_HDLC_LINK_SETUP	0x04	/* set up HDLC link */ 
-#define X25_HDLC_LINK_DISC	0x05	/* disconnect DHLC link */
-#define X25_HDLC_LINK_STATUS	0x06	/* read DHLC link status */
-#define X25_HDLC_READ_STATS	0x07	/* read operational statistics */
-#define X25_HDLC_FLUSH_STATS	0x08 	/* flush operational statistics */
-#define X25_HDLC_READ_COMM_ERR	0x09 	/* read error statistics */
-#define X25_HDLC_FLUSH_COMM_ERR	0x0A	/* flush error statistics */
-#define X25_HDLC_FLUSH_BUFFERS	0x0D	/* flush HDLC-level data buffers */
-#define X25_HDLC_SPRVS_CNT_STAT 0x0F	/* read surervisory count status */
-#define X25_HDLC_SEND_UI_FRAME	0x10	/* send unnumbered information frame */
-#define X25_HDLC_WRITE		0x11	/* send HDLC information frame */
-#define X25_HDLC_READ		0x21	/* read HDLC information frame */
-#define X25_HDLC_READ_CONFIG	0x12	/* read HDLC configuration */
-#define X25_HDLC_SET_CONFIG	0x13	/* set HDLC configuration */
-#define SET_PROTOCOL_LEVEL	0x1F	/* set protocol level */
-/*----- X.25-level commands -----------*/
-#define X25_READ		0x22	/* read X.25 packet */
-#define X25_WRITE		0x23	/* send X.25 packet */
-#define X25_PLACE_CALL		0x30	/* place a call on SVC */
-#define X25_ACCEPT_CALL		0x31	/* accept incomming call */
-#define X25_CLEAR_CALL		0x32	/* clear call */
-#define X25_CLEAR_CONFRM	0x33	/* send clear confirmation packet */
-#define X25_RESET		0x34	/* send reset request packet */
-#define X25_RESET_CONFRM	0x35	/* send reset confirmation packet */
-#define X25_RESTART		0x36	/* send restart request packet */
-#define X25_RESTART_CONFRM	0x37	/* send restart confirmation packet */
-#define X25_INTERRUPT		0x38	/* send interrupt request packet */
-#define X25_INTERRUPT_CONFRM	0x39	/* send interrupt confirmation pkt */
-#define X25_REGISTRATION_RQST	0x3A	/* send registration request packet */
-#define X25_REGISTRATION_CONFRM	0x3B	/* send registration confirmation */
-#define X25_IS_DATA_AVAILABLE	0x40	/* querry receive queue */
-#define X25_INCOMMING_CALL_CTL	0x41	/* select incomming call options */
-#define X25_CONFIGURE_PVC	0x42	/* configure PVC */
-#define X25_GET_ACTIVE_CHANNELS	0x43	/* get a list of active circuits */
-#define X25_READ_CHANNEL_CONFIG	0x44	/* read virt. circuit configuration */
-#define X25_FLUSH_DATA_BUFFERS	0x45	/* flush X.25-level data buffers */
-#define X25_READ_HISTORY_TABLE	0x46	/* read asynchronous event log */
-#define X25_HISTORY_TABLE_CTL	0x47	/* control asynchronous event log */
-#define	X25_GET_TX_D_BIT_STATUS	0x48	/* is packet with D-bit acknowleged */
-#define	X25_READ_STATISTICS	0x49	/* read X.25-level statistics */
-#define	X25_FLUSH_STATISTICS	0x4A	/* flush X.25-level statistics */
-#define	X25_READ_CONFIGURATION	0x50	/* read HDLC & X.25 configuration */
-#define	X25_SET_CONFIGURATION	0x51	/* set HDLC & X.25 configuration */
-
-/*
- * Defines for the 'result' field.
- */
-/*----- General results ---------------*/
-#define X25RES_OK		0x00
-#define X25RES_ERROR		0x01
-#define X25RES_LINK_NOT_IN_ABM	0x02	/* link is not in ABM mode */
-#define X25RES_LINK_CLOSED	0x03
-#define X25RES_INVAL_LENGTH	0x04
-#define X25RES_INVAL_CMD	0x05
-#define X25RES_UNNUMBERED_FRAME	0x06	/* unnunbered frame received */
-#define X25RES_FRM_REJECT_MODE	0x07	/* link is in Frame Reject mode */
-#define X25RES_MODEM_FAILURE	0x08	/* DCD and/or CTS dropped */
-#define X25RES_N2_RETRY_LIMIT	0x09	/* N2 retry limit has been exceeded */
-#define X25RES_INVAL_LCN	0x30	/* invalid logical channel number */
-#define X25RES_INVAL_STATE	0x31	/* channel is not in data xfer mode */
-#define X25RES_INVAL_DATA_LEN	0x32	/* invalid data length */
-#define X25RES_NOT_READY	0x33	/* no data available / buffers full */
-#define X25RES_NETWORK_DOWN	0x34
-#define X25RES_CHANNEL_IN_USE	0x35	/* there is data queued on this LCN */
-#define X25RES_REGST_NOT_SUPPRT	0x36	/* registration not supported */
-#define X25RES_INVAL_FORMAT	0x37	/* invalid packet format */
-#define X25RES_D_BIT_NOT_SUPPRT	0x38	/* D-bit pragmatics not supported */
-#define X25RES_FACIL_NOT_SUPPRT	0x39	/* Call facility not supported */
-#define X25RES_INVAL_CALL_ARG	0x3A	/* errorneous call arguments */
-#define X25RES_INVAL_CALL_DATA	0x3B	/* errorneous call user data */
-#define X25RES_ASYNC_PACKET	0x40	/* asynchronous packet received */
-#define X25RES_PROTO_VIOLATION	0x41	/* protocol violation occurred */
-#define X25RES_PKT_TIMEOUT	0x42	/* X.25 packet time out */
-#define X25RES_PKT_RETRY_LIMIT	0x43	/* X.25 packet retry limit exceeded */
-/*----- Command-dependent results -----*/
-#define X25RES_LINK_DISC	0x00	/* HDLC_LINK_STATUS */
-#define X25RES_LINK_IN_ABM	0x01	/* HDLC_LINK_STATUS */
-#define X25RES_NO_DATA		0x01	/* HDLC_READ/READ_TRACE_DATA*/
-#define X25RES_TRACE_INACTIVE	0x02	/* READ_TRACE_DATA */
-#define X25RES_LINK_IS_OPEN	0x01	/* HDLC_LINK_OPEN */
-#define X25RES_LINK_IS_DISC	0x02	/* HDLC_LINK_DISC */
-#define X25RES_LINK_IS_CLOSED	0x03	/* HDLC_LINK_CLOSE */
-#define X25RES_INVAL_PARAM	0x31	/* INCOMMING_CALL_CTL */
-#define X25RES_INVAL_CONFIG	0x35	/* REGISTR_RQST/CONFRM */
-
-/*
- * Defines for the 'qdm_bits' field.
- */
-#define X25CMD_Q_BIT_MASK	0x04
-#define X25CMD_D_BIT_MASK	0x02
-#define X25CMD_M_BIT_MASK	0x01
-
-/*
- * Defines for the 'pkt_type' field.
- */
-/*----- Asynchronous events ------*/
-#define ASE_CLEAR_RQST		0x02
-#define ASE_RESET_RQST		0x04
-#define ASE_RESTART_RQST	0x08
-#define ASE_INTERRUPT		0x10
-#define ASE_DTE_REGISTR_RQST	0x20
-#define ASE_CALL_RQST		0x30
-#define ASE_CALL_ACCEPTED	0x31
-#define ASE_CLEAR_CONFRM	0x32
-#define ASE_RESET_CONFRM	0x33
-#define ASE_RESTART_CONFRM	0x34
-#define ASE_INTERRUPT_CONFRM	0x35
-#define ASE_DCE_REGISTR_CONFRM	0x36
-#define ASE_DIAGNOSTIC		0x37
-#define ASE_CALL_AUTO_CLEAR	0x38
-#define AUTO_RESPONSE_FLAG	0x80
-/*----- Time-Out events ----------*/
-#define TOE_RESTART_RQST	0x03
-#define TOE_CALL_RQST		0x05
-#define TOE_CLEAR_RQST		0x08
-#define TOE_RESET_RQST		0x0A
-/*----- Protocol Violation events */
-#define PVE_CLEAR_RQST		0x32
-#define PVE_RESET_RQST		0x33
-#define PVE_RESTART_RQST	0x34
-#define PVE_DIAGNOSTIC		0x37
-
-#define INTR_ON_RX_FRAME            0x01
-#define INTR_ON_TX_FRAME            0x02
-#define INTR_ON_MODEM_STATUS_CHANGE 0x04
-#define INTR_ON_COMMAND_COMPLETE    0x08
-#define INTR_ON_X25_ASY_TRANSACTION 0x10
-#define INTR_ON_TIMER		    0x40
-#define DIRECT_RX_INTR_USAGE        0x80
-
-#define NO_INTR_PENDING  	        0x00
-#define RX_INTR_PENDING			0x01	
-#define TX_INTR_PENDING			0x02
-#define MODEM_INTR_PENDING		0x04
-#define COMMAND_COMPLETE_INTR_PENDING 	0x08
-#define X25_ASY_TRANS_INTR_PENDING	0x10
-#define TIMER_INTR_PENDING		0x40
-
-/*----------------------------------------------------------------------------
- * X.25 Mailbox.
- *	This structure is located at offsets X25_MBOX_OFFS and X25_RXMBOX_OFFS
- *	into shared memory window.
- */
-typedef struct X25Mbox
-{
-	unsigned char opflag	PACKED;	/* 00h: execution flag */
-	TX25Cmd cmd		PACKED;	/* 01h: command block */
-	unsigned char data[1]	PACKED;	/* 10h: data buffer */
-} TX25Mbox;
-
-/*----------------------------------------------------------------------------
- * X.25 Time Stamp Structure.
- */
-typedef struct X25TimeStamp
-{
-	unsigned char month	PACKED;
-	unsigned char date	PACKED;
-	unsigned char sec	PACKED;
-	unsigned char min	PACKED;
-	unsigned char hour	PACKED;
-} TX25TimeStamp;
-
-/*----------------------------------------------------------------------------
- * X.25 Status Block.
- *	This structure is located at offset X25_STATUS_OFF into shared memory
- *	window.
- */
-typedef struct X25Status
-{
-	unsigned short pvc_map	PACKED;	/* 00h: PVC map */
-	unsigned short icc_map	PACKED;	/* 02h: Incomming Chan. map */
-	unsigned short twc_map	PACKED;	/* 04h: Two-way Cnan. map */
-	unsigned short ogc_map	PACKED;	/* 06h: Outgoing Chan. map */
-	TX25TimeStamp tstamp	PACKED;	/* 08h: timestamp (BCD) */
-	unsigned char iflags	PACKED;	/* 0Dh: interrupt flags */
-	unsigned char imask     PACKED; /* 0Eh: interrupt mask  */
-	unsigned char resrv	PACKED;	/* 0Eh: */
-	unsigned char gflags	PACKED;	/* 10h: misc. HDLC/X25 flags */
-	unsigned char cflags[X25_MAX_CHAN] PACKED; /* channel status bytes */
-} TX25Status;
-
-/*
- * Bitmasks for the 'iflags' field.
- */
-#define X25_RX_INTR	0x01	/* receive interrupt */
-#define X25_TX_INTR	0x02	/* transmit interrupt */
-#define X25_MODEM_INTR	0x04	/* modem status interrupt (CTS/DCD) */
-#define X25_EVENT_INTR	0x10	/* asyncronous event encountered */
-#define X25_CMD_INTR	0x08	/* interface command complete */
-
-/*
- * Bitmasks for the 'gflags' field.
- */
-#define X25_HDLC_ABM	0x01	/* HDLC is in ABM mode */
-#define X25_RX_READY	0x02	/* X.25 data available */
-#define X25_TRACE_READY	0x08	/* trace data available */
-#define X25_EVENT_IND	0x20	/* asynchronous event indicator */
-#define X25_TX_READY	0x40	/* space is available in Tx buf.*/
-
-/*
- * Bitmasks for the 'cflags' field.
- */
-#define X25_XFER_MODE	0x80	/* channel is in data transfer mode */
-#define X25_TXWIN_OPEN	0x40	/* transmit window open */
-#define X25_RXBUF_MASK	0x3F	/* number of data buffers available */
-
-/*****************************************************************************
- * Following definitions structurize contents of the TX25Mbox.data field for
- * different X.25 interface commands.
- ****************************************************************************/
-
-/* ---------------------------------------------------------------------------
- * X25_SET_GLOBAL_VARS Command.
- */
-typedef struct X25GlobalVars
-{
-	unsigned char resrv	PACKED;	/* 00h: reserved */
-	unsigned char dtrCtl	PACKED;	/* 01h: DTR control code */
-	unsigned char resErr	PACKED;	/* 01h: '1' - reset modem error */
-} TX25GlobalVars;
-
-/*
- * Defines for the 'dtrCtl' field.
- */
-#define X25_RAISE_DTR	0x01
-#define X25_DROP_DTR	0x02
-
-/* ---------------------------------------------------------------------------
- * X25_READ_MODEM_STATUS Command.
- */
-typedef struct X25ModemStatus
-{
-	unsigned char	status	PACKED;		/* 00h: modem status */
-} TX25ModemStatus;
-
-/*
- * Defines for the 'status' field.
- */
-#define X25_CTS_MASK	0x20
-#define X25_DCD_MASK	0x08
-
-/* ---------------------------------------------------------------------------
- * X25_HDLC_LINK_STATUS Command.
- */
-typedef struct X25LinkStatus
-{
-	unsigned char txQueued	PACKED;	/* 00h: queued Tx I-frames*/
-	unsigned char rxQueued	PACKED;	/* 01h: queued Rx I-frames*/
-	unsigned char station	PACKED;	/* 02h: DTE/DCE config. */
-	unsigned char reserved	PACKED;	/* 03h: reserved */
-	unsigned char sfTally	PACKED;	/* 04h: supervisory frame tally */
-} TX25LinkStatus;
-
-/*
- * Defines for the 'station' field.
- */
-#define	X25_STATION_DTE	0x01	/* station configured as DTE */
-#define X25_STATION_DCE	0x02	/* station configured as DCE */
-
-/* ---------------------------------------------------------------------------
- * X25_HDLC_READ_STATS Command.
- */
-typedef struct HdlcStats
-{						/*	a number of ... */
-	unsigned short rxIFrames	PACKED;	/* 00h: ready Rx I-frames */
-	unsigned short rxNoseq		PACKED;	/* 02h: frms out-of-sequence */
-	unsigned short rxNodata		PACKED;	/* 04h: I-frms without data */
-	unsigned short rxDiscarded	PACKED;	/* 06h: discarded frames */
-	unsigned short rxTooLong	PACKED;	/* 08h: frames too long */
-	unsigned short rxBadAddr	PACKED;	/* 0Ah: frms with inval.addr*/
-	unsigned short txAcked		PACKED;	/* 0Ch: acknowledged I-frms */
-	unsigned short txRetransm	PACKED;	/* 0Eh: re-transmit. I-frms */
-	unsigned short t1Timeout	PACKED;	/* 10h: T1 timeouts */
-	unsigned short rxSABM		PACKED;	/* 12h: received SABM frames */
-	unsigned short rxDISC		PACKED;	/* 14h: received DISC frames */
-	unsigned short rxDM		PACKED;	/* 16h: received DM frames */
-	unsigned short rxFRMR		PACKED;	/* 18h: FRMR frames received */
-	unsigned short txSABM		PACKED;	/* 1Ah: transm. SABM frames*/
-	unsigned short txDISC		PACKED;	/* 1Ch: transm. DISC frames*/
-	unsigned short txDM		PACKED;	/* 1Eh: transm. DM frames */
-	unsigned short txFRMR		PACKED;	/* 20h: transm. FRMR frames*/
-} THdlcStats;
-
-/* ---------------------------------------------------------------------------
- * X25_HDLC_READ_COMM_ERR Command.
- */
-typedef struct HdlcCommErr
-{						/*	a number of ... */
-	unsigned char rxOverrun		PACKED;	/* 00h: Rx overrun errors */
-	unsigned char rxBadCrc		PACKED;	/* 01h: Rx CRC errors */
-	unsigned char rxAborted		PACKED;	/* 02h: Rx aborted frames */
-	unsigned char rxDropped		PACKED;	/* 03h: frames lost */
-	unsigned char txAborted		PACKED;	/* 04h: Tx aborted frames */
-	unsigned char txUnderrun	PACKED;	/* 05h: Tx underrun errors */
-	unsigned char txMissIntr	PACKED;	/* 06h: missed underrun ints */
-	unsigned char reserved		PACKED;	/* 07h: reserved */
-	unsigned char droppedDCD	PACKED;	/* 08h: times DCD dropped */
-	unsigned char droppedCTS	PACKED;	/* 09h: times CTS dropped */
-} THdlcCommErr;
-
-/* ---------------------------------------------------------------------------
- * X25_SET_CONFIGURATION & X25_READ_CONFIGURATION Commands.
- */
-typedef struct X25Config
-{
-unsigned char baudRate		PACKED;	/* 00h:  */
-	unsigned char t1		PACKED;	/* 01h:  */
-	unsigned char t2		PACKED;	/* 02h:  */
-	unsigned char n2		PACKED;	/* 03h:  */
-	unsigned short hdlcMTU		PACKED;	/* 04h:  */
-	unsigned char hdlcWindow	PACKED;	/* 06h:  */
-	unsigned char t4		PACKED;	/* 07h:  */
-	unsigned char autoModem		PACKED;	/* 08h:  */
-	unsigned char autoHdlc		PACKED;	/* 09h:  */
-	unsigned char hdlcOptions	PACKED;	/* 0Ah:  */
-	unsigned char station		PACKED;	/* 0Bh:  */
-	unsigned char pktWindow		PACKED;	/* 0Ch:  */
-	unsigned short defPktSize	PACKED;	/* 0Dh:  */
-	unsigned short pktMTU		PACKED;	/* 0Fh:  */
-	unsigned short loPVC		PACKED;	/* 11h:  */
-	unsigned short hiPVC		PACKED;	/* 13h:  */
-	unsigned short loIncommingSVC	PACKED;	/* 15h:  */
-	unsigned short hiIncommingSVC	PACKED;	/* 17h:  */
-	unsigned short loTwoWaySVC	PACKED;	/* 19h:  */
-	unsigned short hiTwoWaySVC	PACKED;	/* 1Bh:  */
-	unsigned short loOutgoingSVC	PACKED;	/* 1Dh:  */
-	unsigned short hiOutgoingSVC	PACKED;	/* 1Fh:  */
-	unsigned short options		PACKED;	/* 21h:  */
-	unsigned char responseOpt	PACKED;	/* 23h:  */
-	unsigned short facil1		PACKED;	/* 24h:  */
-	unsigned short facil2		PACKED;	/* 26h:  */
-	unsigned short ccittFacil	PACKED;	/* 28h:  */
-	unsigned short otherFacil	PACKED;	/* 2Ah:  */
-	unsigned short ccittCompat	PACKED;	/* 2Ch:  */
-	unsigned char t10t20		PACKED;	/* 2Eh:  */
-	unsigned char t11t21		PACKED;	/* 2Fh:  */
-	unsigned char t12t22		PACKED;	/* 30h:  */
-	unsigned char t13t23		PACKED;	/* 31h:  */
-	unsigned char t16t26		PACKED;	/* 32H:  */
-	unsigned char t28		PACKED;	/* 33h:  */
-	unsigned char r10r20		PACKED;	/* 34h:  */
-	unsigned char r12r22		PACKED;	/* 35h:  */
-	unsigned char r13r23		PACKED;	/* 36h:  */
-} TX25Config;
-
-/* ---------------------------------------------------------------------------
- * X25_READ_CHANNEL_CONFIG Command.
- */
-typedef struct X25ChanAlloc			/*----- Channel allocation -*/
-{
-	unsigned short loPVC		PACKED;	/* 00h: lowest PVC number */
-	unsigned short hiPVC		PACKED;	/* 02h: highest PVC number */
-	unsigned short loIncommingSVC	PACKED;	/* 04h: lowest incoming SVC */
-	unsigned short hiIncommingSVC	PACKED;	/* 06h: highest incoming SVC */
-	unsigned short loTwoWaySVC	PACKED;	/* 08h: lowest two-way SVC */
-	unsigned short hiTwoWaySVC	PACKED;	/* 0Ah: highest two-way SVC */
-	unsigned short loOutgoingSVC	PACKED;	/* 0Ch: lowest outgoing SVC */
-	unsigned short hiOutgoingSVC	PACKED;	/* 0Eh: highest outgoing SVC */
-} TX25ChanAlloc;
-
-typedef struct X25ChanCfg		/*------ Channel configuration -----*/
-{
-	unsigned char type	PACKED;	/* 00h: channel type */
-	unsigned char txConf	PACKED;	/* 01h: Tx packet and window sizes */
-	unsigned char rxConf	PACKED;	/* 01h: Rx packet and window sizes */
-} TX25ChanCfg;
-
-/*
- * Defines for the 'type' field.
- */
-#define	X25_PVC  	0x01	/* PVC */
-#define	X25_SVC_IN	0x03	/* Incoming SVC */
-#define	X25_SVC_TWOWAY	0x07	/* Two-way SVC */
-#define	X25_SVC_OUT	0x0B	/* Outgoing SVC */
-
-/*----------------------------------------------------------------------------
- * X25_READ_STATISTICS Command.
- */
-typedef struct X25Stats
-{						/* number of packets Tx/Rx'ed */
-	unsigned short txRestartRqst	PACKED;	/* 00h: Restart Request */
-	unsigned short rxRestartRqst	PACKED;	/* 02h: Restart Request */
-	unsigned short txRestartConf	PACKED;	/* 04h: Restart Confirmation */
-	unsigned short rxRestartConf	PACKED;	/* 06h: Restart Confirmation */
-	unsigned short txResetRqst	PACKED;	/* 08h: Reset Request */
-	unsigned short rxResetRqst	PACKED;	/* 0Ah: Reset Request */
-	unsigned short txResetConf	PACKED;	/* 0Ch: Reset Confirmation */
-	unsigned short rxResetConf	PACKED;	/* 0Eh: Reset Confirmation */
-	unsigned short txCallRequest	PACKED;	/* 10h: Call Request */
-	unsigned short rxCallRequest	PACKED;	/* 12h: Call Request */
-	unsigned short txCallAccept	PACKED;	/* 14h: Call Accept */
-	unsigned short rxCallAccept	PACKED;	/* 16h: Call Accept */
-	unsigned short txClearRqst	PACKED;	/* 18h: Clear Request */
-	unsigned short rxClearRqst	PACKED;	/* 1Ah: Clear Request */
-	unsigned short txClearConf	PACKED;	/* 1Ch: Clear Confirmation */
-	unsigned short rxClearConf	PACKED;	/* 1Eh: Clear Confirmation */
-	unsigned short txDiagnostic	PACKED;	/* 20h: Diagnostic */
-	unsigned short rxDiagnostic	PACKED;	/* 22h: Diagnostic */
-	unsigned short txRegRqst	PACKED;	/* 24h: Registration Request */
-	unsigned short rxRegRqst	PACKED;	/* 26h: Registration Request */
-	unsigned short txRegConf	PACKED;	/* 28h: Registration Confirm.*/
-	unsigned short rxRegConf	PACKED;	/* 2Ah: Registration Confirm.*/
-	unsigned short txInterrupt	PACKED;	/* 2Ch: Interrupt */
-	unsigned short rxInterrupt	PACKED;	/* 2Eh: Interrupt */
-	unsigned short txIntrConf	PACKED;	/* 30h: Interrupt Confirm. */
-	unsigned short rxIntrConf	PACKED;	/* 32h: Interrupt Confirm. */
-	unsigned short txData		PACKED;	/* 34h: Data */
-	unsigned short rxData		PACKED;	/* 36h: Data */
-	unsigned short txRR		PACKED;	/* 38h: RR */
-	unsigned short rxRR		PACKED;	/* 3Ah: RR */
-	unsigned short txRNR		PACKED;	/* 3Ch: RNR */
-	unsigned short rxRNR		PACKED;	/* 3Eh: RNR */
-} TX25Stats;
-
-/*----------------------------------------------------------------------------
- * X25_READ_HISTORY_TABLE Command.
- */
-typedef struct X25EventLog
-{
-	unsigned char	type	PACKED;	/* 00h: transaction type */
-	unsigned short	lcn	PACKED;	/* 01h: logical channel num */
-	unsigned char	packet	PACKED;	/* 03h: async packet type */
-	unsigned char	cause	PACKED;	/* 04h: X.25 cause field */
-	unsigned char	diag	PACKED;	/* 05h: X.25 diag field */
-	TX25TimeStamp	ts	PACKED;	/* 06h: time stamp */
-} TX25EventLog;
-
-/*
- * Defines for the 'type' field.
- */
-#define X25LOG_INCOMMING	0x00
-#define X25LOG_APPLICATION 	0x01
-#define X25LOG_AUTOMATIC	0x02
-#define X25LOG_ERROR		0x04
-#define X25LOG_TIMEOUT		0x08
-#define X25LOG_RECOVERY		0x10
-
-/*
- * Defines for the 'packet' field.
- */
-#define X25LOG_CALL_RQST	0x0B
-#define X25LOG_CALL_ACCEPTED	0x0F
-#define X25LOG_CLEAR_RQST	0x13
-#define X25LOG_CLEAR_CONFRM	0x17
-#define X25LOG_RESET_RQST	0x1B
-#define X25LOG_RESET_CONFRM	0x1F
-#define X25LOG_RESTART_RQST	0xFB
-#define X25LOG_RESTART_COMFRM	0xFF
-#define X25LOG_DIAGNOSTIC	0xF1
-#define X25LOG_DTE_REG_RQST	0xF3
-#define X25LOG_DTE_REG_COMFRM	0xF7
-
-/* ---------------------------------------------------------------------------
- * X25_TRACE_CONFIGURE Command.
- */
-typedef struct X25TraceCfg
-{
-	unsigned char flags	PACKED;	/* 00h: trace configuration flags */
-	unsigned char timeout	PACKED;	/* 01h: timeout for trace delay mode*/
-} TX25TraceCfg;
-
-/*
- * Defines for the 'flags' field.
- */
-#define X25_TRC_ENABLE		0x01	/* bit0: '1' - trace enabled */
-#define X25_TRC_TIMESTAMP	0x02	/* bit1: '1' - time stamping enabled*/
-#define X25_TRC_DELAY		0x04	/* bit2: '1' - trace delay enabled */
-#define X25_TRC_DATA		0x08	/* bit3: '1' - trace data packets */
-#define X25_TRC_SUPERVISORY	0x10    /* bit4: '1' - trace suprvisory pkts*/
-#define X25_TRC_ASYNCHRONOUS	0x20	/* bit5: '1' - trace asynch. packets*/
-#define X25_TRC_HDLC		0x40	/* bit6: '1' - trace all packets */
-#define X25_TRC_READ		0x80	/* bit7: '1' - get current config. */
-
-/* ---------------------------------------------------------------------------
- * X25_READ_TRACE_DATA Command.
- */
-typedef struct X25Trace			/*----- Trace data structure -------*/
-{
-	unsigned short length	PACKED;	/* 00h: trace data length */
-	unsigned char type	PACKED;	/* 02h: trace type */
-	unsigned char lost_cnt	PACKED;	/* 03h: N of traces lost */
-	TX25TimeStamp tstamp	PACKED;	/* 04h: mon/date/sec/min/hour */
-	unsigned short millisec	PACKED;	/* 09h: ms time stamp */
-	unsigned char data[0]	PACKED;	/* 0Bh: traced frame */
-} TX25Trace;
-
-/*
- * Defines for the 'type' field.
- */
-#define X25_TRC_TYPE_MASK	0x0F	/* bits 0..3: trace type */
-#define X25_TRC_TYPE_RX_FRAME	0x00	/* received frame trace */
-#define X25_TRC_TYPE_TX_FRAME	0x01	/* transmitted frame */
-#define X25_TRC_TYPE_ERR_FRAME	0x02	/* error frame */
-
-#define X25_TRC_ERROR_MASK	0xF0	/* bits 4..7: error code */
-#define X25_TRCERR_RX_ABORT	0x10	/* receive abort error */
-#define X25_TRCERR_RX_BADCRC	0x20	/* receive CRC error */
-#define X25_TRCERR_RX_OVERRUN	0x30	/* receiver overrun error */
-#define X25_TRCERR_RX_TOO_LONG	0x40	/* excessive frame length error */
-#define X25_TRCERR_TX_ABORT	0x70	/* aborted frame transmittion error */
-#define X25_TRCERR_TX_UNDERRUN	0x80	/* transmit underrun error */
-
-/*****************************************************************************
- * Following definitions describe HDLC frame and X.25 packet formats.
- ****************************************************************************/
-
-typedef struct HDLCFrame		/*----- DHLC Frame Format ----------*/
-{
-	unsigned char addr	PACKED;	/* address field */
-	unsigned char cntl	PACKED;	/* control field */
-	unsigned char data[0]	PACKED;
-} THDLCFrame;
-
-typedef struct X25Pkt			/*----- X.25 Paket Format ----------*/
-{
-	unsigned char lcn_hi	PACKED;	/* 4 MSB of Logical Channel Number */
-	unsigned char lcn_lo	PACKED;	/* 8 LSB of Logical Channel Number */
-	unsigned char type	PACKED;
-	unsigned char data[0]	PACKED;
-} TX25Pkt;
-
-/*
- * Defines for the 'lcn_hi' field.
- */
-#define	X25_Q_BIT_MASK		0x80	/* Data Qualifier Bit mask */
-#define	X25_D_BIT_MASK		0x40	/* Delivery Confirmation Bit mask */
-#define	X25_M_BITS_MASK		0x30	/* Modulo Bits mask */
-#define	X25_LCN_MSB_MASK	0x0F	/* LCN most significant bits mask */
-
-/*
- * Defines for the 'type' field.
- */
-#define	X25PKT_DATA		0x01	/* Data packet mask */
-#define	X25PKT_SUPERVISORY	0x02	/* Supervisory packet mask */
-#define	X25PKT_CALL_RQST	0x0B	/* Call Request/Incoming */
-#define	X25PKT_CALL_ACCEPTED	0x0F	/* Call Accepted/Connected */
-#define	X25PKT_CLEAR_RQST	0x13	/* Clear Request/Indication */
-#define	X25PKT_CLEAR_CONFRM	0x17	/* Clear Confirmation */
-#define	X25PKT_RESET_RQST	0x1B	/* Reset Request/Indication */
-#define	X25PKT_RESET_CONFRM	0x1F	/* Reset Confirmation */
-#define	X25PKT_RESTART_RQST	0xFB	/* Restart Request/Indication */
-#define	X25PKT_RESTART_CONFRM	0xFF	/* Restart Confirmation */
-#define	X25PKT_INTERRUPT	0x23	/* Interrupt */
-#define	X25PKT_INTERRUPT_CONFRM	0x27	/* Interrupt Confirmation */
-#define	X25PKT_DIAGNOSTIC	0xF1	/* Diagnostic */
-#define	X25PKT_REGISTR_RQST	0xF3	/* Registration Request */
-#define	X25PKT_REGISTR_CONFRM	0xF7	/* Registration Confirmation */
-#define	X25PKT_RR_MASKED	0x01	/* Receive Ready packet after masking */
-#define	X25PKT_RNR_MASKED	0x05	/* Receive Not Ready after masking  */
-
-
-typedef struct {
-	TX25Cmd cmd		PACKED;
-	char data[X25_MAX_DATA]	PACKED;
-} mbox_cmd_t;
-
-
-typedef struct {
-	unsigned char  qdm	PACKED;	/* Q/D/M bits */
-	unsigned char  cause	PACKED;	/* cause field */
-	unsigned char  diagn	PACKED;	/* diagnostics */
-	unsigned char  pktType  PACKED;
-	unsigned short length   PACKED;
-	unsigned char  result	PACKED;
-	unsigned short lcn	PACKED;
-	char reserved[7]	PACKED;
-}x25api_hdr_t;
-
-
-typedef struct {
-	x25api_hdr_t hdr	PACKED;
-	char data[X25_MAX_DATA]	PACKED;
-}x25api_t;
-
-
-/* 
- * XPIPEMON Definitions
- */
-
-/* valid ip_protocol for UDP management */
-#define UDPMGMT_UDP_PROTOCOL 0x11
-#define UDPMGMT_XPIPE_SIGNATURE         "XLINK8ND"
-#define UDPMGMT_DRVRSTATS_SIGNATURE     "DRVSTATS"
-
-/* values for request/reply byte */
-#define UDPMGMT_REQUEST	0x01
-#define UDPMGMT_REPLY	0x02
-#define UDP_OFFSET	12
-
-
-typedef struct {
-	unsigned char opp_flag  PACKED; /* the opp flag */
-	unsigned char command	PACKED;	/* command code */
-	unsigned short length	PACKED;	/* transfer data length */
-	unsigned char result	PACKED;	/* return code */
-	unsigned char pf	PACKED;	/* P/F bit */
-	unsigned short lcn	PACKED;	/* logical channel */
-	unsigned char qdm	PACKED;	/* Q/D/M bits */
-	unsigned char cause	PACKED;	/* cause field */
-	unsigned char diagn	PACKED;	/* diagnostics */
-	unsigned char pktType	PACKED;	/* packet type */
-	unsigned char resrv[4]	PACKED;	/* reserved */
-} cblock_t;
-
-typedef struct {
-	ip_pkt_t 		ip_pkt		PACKED;
-	udp_pkt_t		udp_pkt		PACKED;
-	wp_mgmt_t 		wp_mgmt       	PACKED;
-        cblock_t                cblock          PACKED;
-        unsigned char           data[4080]      PACKED;
-} x25_udp_pkt_t;
-
-
-typedef struct read_hdlc_stat {
-	unsigned short inf_frames_rx_ok PACKED;
-        unsigned short inf_frames_rx_out_of_seq PACKED;
-	unsigned short inf_frames_rx_no_data PACKED;
-	unsigned short inf_frames_rx_dropped PACKED;
-	unsigned short inf_frames_rx_data_too_long PACKED;
-	unsigned short inf_frames_rx_invalid_addr PACKED;
-	unsigned short inf_frames_tx_ok PACKED;
-        unsigned short inf_frames_tx_retransmit PACKED;
-       	unsigned short T1_timeouts PACKED;
-	unsigned short SABM_frames_rx PACKED;
-	unsigned short DISC_frames_rx PACKED;
-	unsigned short DM_frames_rx PACKED;
-	unsigned short FRMR_frames_rx PACKED;
-	unsigned short SABM_frames_tx PACKED;
-	unsigned short DISC_frames_tx PACKED;
-	unsigned short DM_frames_tx PACKED;
-	unsigned short FRMR_frames_tx PACKED;
-} read_hdlc_stat_t;
-
-typedef struct read_comms_err_stats{
-	unsigned char overrun_err_rx PACKED;
-	unsigned char CRC_err PACKED;
-	unsigned char abort_frames_rx PACKED;
-	unsigned char frames_dropped_buf_full PACKED;
-	unsigned char abort_frames_tx PACKED;
-	unsigned char transmit_underruns PACKED;
-	unsigned char missed_tx_underruns_intr PACKED;
-	unsigned char reserved PACKED;
-	unsigned char DCD_drop PACKED;
-	unsigned char CTS_drop PACKED;
-} read_comms_err_stats_t;
-
-typedef struct trace_data {
-	unsigned short length PACKED;
-	unsigned char  type PACKED;
-	unsigned char  trace_dropped PACKED;
-	unsigned char  reserved[5] PACKED;
-	unsigned short timestamp PACKED;
-        unsigned char  data PACKED;
-} trace_data_t;
-
-enum {UDP_XPIPE_TYPE};
-
-#define XPIPE_ENABLE_TRACING                    0x14
-#define XPIPE_DISABLE_TRACING                   0x14
-#define XPIPE_GET_TRACE_INFO                    0x16
-#define XPIPE_FT1_READ_STATUS                   0x74
-#define XPIPE_DRIVER_STAT_IFSEND                0x75
-#define XPIPE_DRIVER_STAT_INTR                  0x76
-#define XPIPE_DRIVER_STAT_GEN                   0x77
-#define XPIPE_FLUSH_DRIVER_STATS                0x78
-#define XPIPE_ROUTER_UP_TIME                    0x79        
-#define XPIPE_SET_FT1_MODE			0x81
-#define XPIPE_FT1_STATUS_CTRL			0x80
-
-
-/* error messages */
-#define NO_BUFFS_OR_CLOSED_WIN  0x33
-#define DATA_LENGTH_TOO_BIG     0x32
-#define NO_DATA_AVAILABLE       0x33
-#define Z80_TIMEOUT_ERROR       0x0a   
-#define	NO_BUFFS		0x08
-
-
-/* Trace options */
-#define TRACE_DEFAULT		0x03
-#define TRACE_SUPERVISOR_FRMS	0x10
-#define TRACE_ASYNC_FRMS	0x20
-#define TRACE_ALL_HDLC_FRMS	0x40
-#define TRACE_DATA_FRMS		0x08
-
-
-#endif	/* _SDLA_X25_H */
diff --git a/include/linux/sdladrv.h b/include/linux/sdladrv.h
deleted file mode 100644
index c85e103..0000000
--- a/include/linux/sdladrv.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*****************************************************************************
-* sdladrv.h	SDLA Support Module.  Kernel API Definitions.
-*
-* Author: 	Gideon Hack	
-*
-* Copyright:	(c) 1995-2000 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.
-* ============================================================================
-* Jun 02, 1999 	Gideon Hack	Added support for the S514 PCI adapter.
-* Dec 11, 1996	Gene Kozin	Complete overhaul.
-* Oct 17, 1996	Gene Kozin	Minor bug fixes.
-* Jun 12, 1996	Gene Kozin 	Added support for S503 card.
-* Dec 06, 1995	Gene Kozin	Initial version.
-*****************************************************************************/
-#ifndef	_SDLADRV_H
-#define	_SDLADRV_H
-
-
-#define	SDLA_MAXIORANGE	4	/* maximum I/O port range */
-#define	SDLA_WINDOWSIZE	0x2000	/* default dual-port memory window size */
-/****** Data Structures *****************************************************/
-
-/*----------------------------------------------------------------------------
- * Adapter hardware configuration. Pointer to this structure is passed to all
- * APIs.
- */
-typedef struct sdlahw
-{
-	unsigned type;			/* adapter type */
-	unsigned fwid;			/* firmware ID */
-	unsigned port;			/* adapter I/O port base */
-	int irq;			/* interrupt request level */
-	char S514_cpu_no[1];		/* PCI CPU Number */
-	unsigned char S514_slot_no;	/* PCI Slot Number */
-	char auto_pci_cfg;		/* Autodetect PCI Slot */
-	struct pci_dev *pci_dev;	/* PCI device */
-	void * dpmbase;			/* dual-port memory base */
-	unsigned dpmsize;		/* dual-port memory size */
-	unsigned pclk;			/* CPU clock rate, kHz */
-	unsigned long memory;		/* memory size */
-	unsigned long vector;		/* local offset of the DPM window */
-	unsigned io_range;		/* I/O port range */
-	unsigned char regs[SDLA_MAXIORANGE]; /* was written to registers */
-	unsigned reserved[5];
-} sdlahw_t;
-
-/****** Function Prototypes *************************************************/
-
-extern int sdla_setup	(sdlahw_t* hw, void* sfm, unsigned len);
-extern int sdla_down	(sdlahw_t* hw);
-extern void S514_intack  (sdlahw_t* hw, u32 int_status);
-extern void read_S514_int_stat (sdlahw_t* hw, u32* int_status);
-extern int sdla_mapmem	(sdlahw_t* hw, unsigned long addr);
-extern int sdla_peek	(sdlahw_t* hw, unsigned long addr, void* buf,
-			 unsigned len);
-extern int sdla_poke	(sdlahw_t* hw, unsigned long addr, void* buf,
-			 unsigned len);
-extern int sdla_exec	(void* opflag);
-
-extern unsigned wanpipe_hw_probe(void);
-
-#endif	/* _SDLADRV_H */
diff --git a/include/linux/sdlapci.h b/include/linux/sdlapci.h
deleted file mode 100644
index 6f7c904..0000000
--- a/include/linux/sdlapci.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*****************************************************************************
-* sdlapci.h	WANPIPE(tm) Multiprotocol WAN Link Driver.
-*		Definitions for the SDLA PCI adapter.
-*
-* Author:	Gideon Hack	<ghack@sangoma.com>
-*
-* Copyright:	(c) 1999-2000 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.
-* ============================================================================
-* Jun 02, 1999	Gideon Hack	Initial version.
-*****************************************************************************/
-#ifndef	_SDLAPCI_H
-#define	_SDLAPCI_H
-
-/****** Defines *************************************************************/
-
-/* Definitions for identifying and finding S514 PCI adapters */
-#define V3_VENDOR_ID		0x11B0		/* V3 vendor ID number */
-#define V3_DEVICE_ID  		0x0002		/* V3 device ID number */
-#define SANGOMA_SUBSYS_VENDOR 	0x4753		/* ID for Sangoma */
-#define PCI_DEV_SLOT_MASK	0x1F		/* mask for slot numbering */
-#define PCI_IRQ_NOT_ALLOCATED	0xFF		/* interrupt line for no IRQ */
-
-/* Local PCI register offsets */ 
-#define PCI_VENDOR_ID_WORD	0x00		/* vendor ID */
-#define PCI_IO_BASE_DWORD	0x10		/* IO base */	
-#define PCI_MEM_BASE0_DWORD	0x14		/* memory base - apperture 0 */
-#define PCI_MEM_BASE1_DWORD     0x18		/* memory base - apperture 1 */
-#define PCI_SUBSYS_VENDOR_WORD 	0x2C		/* subsystem vendor ID */
-#define PCI_INT_LINE_BYTE	0x3C		/* interrupt line */
-#define PCI_INT_PIN_BYTE	0x3D		/* interrupt pin */
-#define PCI_MAP0_DWORD		0x40		/* PCI to local bus address 0 */
-#define PCI_MAP1_DWORD          0x44		/* PCI to local bus address 1 */
-#define PCI_INT_STATUS          0x48		/* interrupt status */
-#define PCI_INT_CONFIG		0x4C		/* interrupt configuration */
-  
-/* Local PCI register usage */
-#define PCI_MEMORY_ENABLE	0x00000003	/* enable PCI memory */
-#define PCI_CPU_A_MEM_DISABLE	0x00000002	/* disable CPU A memory */
-#define PCI_CPU_B_MEM_DISABLE  	0x00100002	/* disable CPU B memory */
-#define PCI_ENABLE_IRQ_CPU_A	0x005A0004	/* enable IRQ for CPU A */
-#define PCI_ENABLE_IRQ_CPU_B    0x005A0008	/* enable IRQ for CPU B */
-#define PCI_DISABLE_IRQ_CPU_A   0x00000004	/* disable IRQ for CPU A */
-#define PCI_DISABLE_IRQ_CPU_B   0x00000008	/* disable IRQ for CPU B */
- 
-/* Setting for the Interrupt Status register */  
-#define IRQ_CPU_A               0x04            /* IRQ for CPU A */
-#define IRQ_CPU_B               0x08		/* IRQ for CPU B */
-
-/* The maximum size of the S514 memory */
-#define MAX_SIZEOF_S514_MEMORY	(256 * 1024)
-
-/* S514 control register offsets within the memory address space */
-#define S514_CTRL_REG_BYTE	0x80000
- 
-/* S514 adapter control bytes */
-#define S514_CPU_HALT 		0x00
-#define S514_CPU_START		0x01
-
-/* The maximum number of S514 adapters supported */
-#define MAX_S514_CARDS		20	
-
-#define PCI_CARD_TYPE		0x2E
-#define S514_DUAL_CPU		0x12
-#define S514_SINGLE_CPU		0x11
-
-#endif	/* _SDLAPCI_H */
-
diff --git a/include/linux/sdlasfm.h b/include/linux/sdlasfm.h
deleted file mode 100644
index 94aaa8a..0000000
--- a/include/linux/sdlasfm.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*****************************************************************************
-* sdlasfm.h	WANPIPE(tm) Multiprotocol WAN Link Driver.
-*		Definitions for the SDLA Firmware Module (SFM).
-*
-* Author: 	Gideon Hack 	
-*
-* Copyright:	(c) 1995-1999 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.
-* ============================================================================
-* Jun 02, 1999  Gideon Hack	Added support for the S514 adapter.
-* Dec 11, 1996	Gene Kozin	Cosmetic changes
-* Apr 16, 1996	Gene Kozin	Changed adapter & firmware IDs. Version 2
-* Dec 15, 1995	Gene Kozin	Structures chaned
-* Nov 09, 1995	Gene Kozin	Initial version.
-*****************************************************************************/
-#ifndef	_SDLASFM_H
-#define	_SDLASFM_H
-
-/****** Defines *************************************************************/
-
-#define	SFM_VERSION	2
-#define	SFM_SIGNATURE	"SFM - Sangoma SDLA Firmware Module"
-
-/* min/max */
-#define	SFM_IMAGE_SIZE	0x8000	/* max size of SDLA code image file */
-#define	SFM_DESCR_LEN	256	/* max length of description string */
-#define	SFM_MAX_SDLA	16	/* max number of compatible adapters */
-
-/* Adapter types */
-#define SDLA_S502A	5020
-#define SDLA_S502E	5021
-#define SDLA_S503	5030
-#define SDLA_S508	5080
-#define SDLA_S507	5070
-#define SDLA_S509	5090
-#define SDLA_S514	5140
-
-/* S514 PCI adapter CPU numbers */
-#define S514_CPU_A	'A'
-#define S514_CPU_B	'B'
-
-
-/* Firmware identification numbers:
- *    0  ..  999	Test & Diagnostics
- *  1000 .. 1999	Streaming HDLC
- *  2000 .. 2999	Bisync
- *  3000 .. 3999	SDLC
- *  4000 .. 4999	HDLC
- *  5000 .. 5999	X.25
- *  6000 .. 6999	Frame Relay
- *  7000 .. 7999	PPP
- *  8000 .. 8999        Cisco HDLC
- */
-#define	SFID_CALIB502	 200
-#define	SFID_STRM502	1200
-#define	SFID_STRM508	1800
-#define	SFID_BSC502	2200
-#define	SFID_SDLC502	3200
-#define	SFID_HDLC502	4200
-#define	SFID_HDLC508	4800
-#define	SFID_X25_502	5200
-#define	SFID_X25_508	5800
-#define	SFID_FR502	6200
-#define	SFID_FR508	6800
-#define	SFID_PPP502	7200
-#define	SFID_PPP508	7800
-#define SFID_PPP514	7140
-#define	SFID_CHDLC508	8800
-#define SFID_CHDLC514	8140
-
-/****** Data Types **********************************************************/
-
-typedef struct	sfm_info		/* firmware module information */
-{
-	unsigned short	codeid;		/* firmware ID */
-	unsigned short	version;	/* firmaware version number */
-	unsigned short	adapter[SFM_MAX_SDLA]; /* compatible adapter types */
-	unsigned long	memsize;	/* minimum memory size */
-	unsigned short	reserved[2];	/* reserved */
-	unsigned short	startoffs;	/* entry point offset */
-	unsigned short	winoffs;	/* dual-port memory window offset */
-	unsigned short	codeoffs;	/* code load offset */
-	unsigned short	codesize;	/* code size */
-	unsigned short	dataoffs;	/* configuration data load offset */
-	unsigned short	datasize;	/* configuration data size */
-} sfm_info_t;
-
-typedef struct sfm			/* SDLA firmware file structire */
-{
-	char		signature[80];	/* SFM file signature */
-	unsigned short	version;	/* file format version */
-	unsigned short	checksum;	/* info + image */
-	unsigned short	reserved[6];	/* reserved */
-	char		descr[SFM_DESCR_LEN]; /* description string */
-	sfm_info_t	info;		/* firmware module info */
-	unsigned char	image[1];	/* code image (variable size) */
-} sfm_t;
-
-#endif	/* _SDLASFM_H */
-
diff --git a/include/linux/wanpipe.h b/include/linux/wanpipe.h
deleted file mode 100644
index dae9860..0000000
--- a/include/linux/wanpipe.h
+++ /dev/null
@@ -1,483 +0,0 @@
-/*****************************************************************************
-* wanpipe.h	WANPIPE(tm) Multiprotocol WAN Link Driver.
-*		User-level API definitions.
-*
-* Author: 	Nenad Corbic <ncorbic@sangoma.com>
-*		Gideon Hack  	
-*
-* Copyright:	(c) 1995-2000 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.
-* ============================================================================
-* Nov 3,  2000  Nenad Corbic    Added config_id to sdla_t structure.
-*                               Used to determine the protocol running.
-* Jul 13, 2000  Nenad Corbic	Added SyncPPP Support
-* Feb 24, 2000  Nenad Corbic    Added support for x25api driver
-* Oct 04, 1999  Nenad Corbic    New CHDLC and FRAME RELAY code, SMP support
-* Jun 02, 1999  Gideon Hack	Added 'update_call_count' for Cisco HDLC 
-*				support
-* Jun 26, 1998	David Fong	Added 'ip_mode' in sdla_t.u.p for dynamic IP
-*				routing mode configuration
-* Jun 12, 1998	David Fong	Added Cisco HDLC union member in sdla_t
-* Dec 08, 1997	Jaspreet Singh  Added 'authenticator' in union of 'sdla_t' 
-* Nov 26, 1997	Jaspreet Singh	Added 'load_sharing' structure.  Also added 
-*				'devs_struct','dev_to_devtint_next' to 'sdla_t'	
-* Nov 24, 1997	Jaspreet Singh	Added 'irq_dis_if_send_count', 
-*				'irq_dis_poll_count' to 'sdla_t'.
-* Nov 06, 1997	Jaspreet Singh	Added a define called 'INTR_TEST_MODE'
-* Oct 20, 1997	Jaspreet Singh	Added 'buff_intr_mode_unbusy' and 
-*				'dlci_intr_mode_unbusy' to 'sdla_t'
-* Oct 18, 1997	Jaspreet Singh	Added structure to maintain global driver
-*				statistics.
-* Jan 15, 1997	Gene Kozin	Version 3.1.0
-*				 o added UDP management stuff
-* Jan 02, 1997	Gene Kozin	Version 3.0.0
-*****************************************************************************/
-#ifndef	_WANPIPE_H
-#define	_WANPIPE_H
-
-#include <linux/wanrouter.h>
-
-/* Defines */
-
-#ifndef	PACKED
-#define	PACKED	__attribute__((packed))
-#endif
-
-#define	WANPIPE_MAGIC	0x414C4453L	/* signature: 'SDLA' reversed */
-
-/* IOCTL numbers (up to 16) */
-#define	WANPIPE_DUMP	(ROUTER_USER+0)	/* dump adapter's memory */
-#define	WANPIPE_EXEC	(ROUTER_USER+1)	/* execute firmware command */
-
-#define TRACE_ALL                       0x00
-#define TRACE_PROT			0x01
-#define TRACE_DATA			0x02
-
-/* values for request/reply byte */
-#define UDPMGMT_REQUEST	0x01
-#define UDPMGMT_REPLY	0x02
-#define UDP_OFFSET	12
-
-#define MAX_CMD_BUFF 	10
-#define MAX_X25_LCN 	255	/* Maximum number of x25 channels */
-#define MAX_LCN_NUM	4095	/* Maximum lcn number */
-#define MAX_FT1_RETRY 	100
-
-#ifndef AF_WANPIPE
-	#define AF_WANPIPE 25
-	#ifndef PF_WANPIPE
-		#define PF_WANPIPE AF_WANPIPE
-	#endif
-#endif
-
-
-#define TX_TIMEOUT 5*HZ
-
-/* General Critical Flags */
-#define SEND_CRIT	0x00
-#define PERI_CRIT	0x01
-
-/* Chdlc and PPP polling critical flag */
-#define POLL_CRIT	0x03
-
-/* Frame Relay Tx IRQ send critical flag */
-#define SEND_TXIRQ_CRIT 0x02
-
-/* Frame Relay ARP critical flag */
-#define ARP_CRIT	0x03
-
-/* Bit maps for dynamic interface configuration
- * DYN_OPT_ON : turns this option on/off 
- * DEV_DOWN   : device was shutdown by the driver not
- *              by user 
- */
-#define DYN_OPT_ON	0x00
-#define DEV_DOWN	0x01
-
-/*
- * Data structures for IOCTL calls.
- */
-
-typedef struct sdla_dump	/* WANPIPE_DUMP */
-{
-	unsigned long magic;	/* for verification */
-	unsigned long offset;	/* absolute adapter memory address */
-	unsigned long length;	/* block length */
-	void* ptr;		/* -> buffer */
-} sdla_dump_t;
-
-typedef struct sdla_exec	/* WANPIPE_EXEC */
-{
-	unsigned long magic;	/* for verification */
-	void* cmd;		/* -> command structure */
-	void* data;		/* -> data buffer */
-} sdla_exec_t;
-
-/* UDP management stuff */
-
-typedef struct wum_header
-{
-	unsigned char signature[8];	/* 00h: signature */
-	unsigned char type;		/* 08h: request/reply */
-	unsigned char command;		/* 09h: commnand */
-	unsigned char reserved[6];	/* 0Ah: reserved */
-} wum_header_t;
-
-/*************************************************************************
- Data Structure for global statistics
-*************************************************************************/
-
-typedef struct global_stats
-{
-	unsigned long isr_entry;
-	unsigned long isr_already_critical;		
-	unsigned long isr_rx;
-	unsigned long isr_tx;
-	unsigned long isr_intr_test;
-	unsigned long isr_spurious;
-	unsigned long isr_enable_tx_int;
-	unsigned long rx_intr_corrupt_rx_bfr;
-	unsigned long rx_intr_on_orphaned_DLCI;
-	unsigned long rx_intr_dev_not_started;
-	unsigned long tx_intr_dev_not_started;
-	unsigned long poll_entry;
-	unsigned long poll_already_critical;
-	unsigned long poll_processed;
-	unsigned long poll_tbusy_bad_status;
-	unsigned long poll_host_disable_irq;
-	unsigned long poll_host_enable_irq;
-
-} global_stats_t;
-
-
-typedef struct{
-	unsigned short	udp_src_port		PACKED;
-	unsigned short	udp_dst_port		PACKED;
-	unsigned short	udp_length		PACKED;
-	unsigned short	udp_checksum		PACKED;
-} udp_pkt_t;
-
-
-typedef struct {
-	unsigned char	ver_inet_hdr_length	PACKED;
-	unsigned char	service_type		PACKED;
-	unsigned short	total_length		PACKED;
-	unsigned short	identifier		PACKED;
-	unsigned short	flags_frag_offset	PACKED;
-	unsigned char	ttl			PACKED;
-	unsigned char	protocol		PACKED;
-	unsigned short	hdr_checksum		PACKED;
-	unsigned long	ip_src_address		PACKED;
-	unsigned long	ip_dst_address		PACKED;
-} ip_pkt_t;
-
-
-typedef struct {
-        unsigned char           signature[8]    PACKED;
-        unsigned char           request_reply   PACKED;
-        unsigned char           id              PACKED;
-        unsigned char           reserved[6]     PACKED;
-} wp_mgmt_t;
-
-/*************************************************************************
- Data Structure for if_send  statistics
-*************************************************************************/  
-typedef struct if_send_stat{
-	unsigned long if_send_entry;
-	unsigned long if_send_skb_null;
-	unsigned long if_send_broadcast;
-	unsigned long if_send_multicast;
-	unsigned long if_send_critical_ISR;
-	unsigned long if_send_critical_non_ISR;
-	unsigned long if_send_tbusy;
-	unsigned long if_send_tbusy_timeout;
-	unsigned long if_send_PIPE_request;
-	unsigned long if_send_wan_disconnected;
-	unsigned long if_send_dlci_disconnected;
-	unsigned long if_send_no_bfrs;
-	unsigned long if_send_adptr_bfrs_full;
-	unsigned long if_send_bfr_passed_to_adptr;
-	unsigned long if_send_protocol_error;
-       	unsigned long if_send_bfr_not_passed_to_adptr;
-       	unsigned long if_send_tx_int_enabled;
-        unsigned long if_send_consec_send_fail; 
-} if_send_stat_t;
-
-typedef struct rx_intr_stat{
-	unsigned long rx_intr_no_socket;
-	unsigned long rx_intr_dev_not_started;
-	unsigned long rx_intr_PIPE_request;
-	unsigned long rx_intr_bfr_not_passed_to_stack;
-	unsigned long rx_intr_bfr_passed_to_stack;
-} rx_intr_stat_t;	
-
-typedef struct pipe_mgmt_stat{
-	unsigned long UDP_PIPE_mgmt_kmalloc_err;
-	unsigned long UDP_PIPE_mgmt_direction_err;
-	unsigned long UDP_PIPE_mgmt_adptr_type_err;
-	unsigned long UDP_PIPE_mgmt_adptr_cmnd_OK;
-	unsigned long UDP_PIPE_mgmt_adptr_cmnd_timeout;
-	unsigned long UDP_PIPE_mgmt_adptr_send_passed;
-	unsigned long UDP_PIPE_mgmt_adptr_send_failed;
-	unsigned long UDP_PIPE_mgmt_not_passed_to_stack;
-	unsigned long UDP_PIPE_mgmt_passed_to_stack;
-	unsigned long UDP_PIPE_mgmt_no_socket;
-        unsigned long UDP_PIPE_mgmt_passed_to_adptr;
-} pipe_mgmt_stat_t;
-
-
-typedef struct {
-	struct sk_buff *skb;
-} bh_data_t, cmd_data_t;
-
-#define MAX_LGTH_UDP_MGNT_PKT 2000
- 
-
-/* This is used for interrupt testing */
-#define INTR_TEST_MODE	0x02
-
-#define	WUM_SIGNATURE_L	0x50495046
-#define	WUM_SIGNATURE_H	0x444E3845
-
-#define	WUM_KILL	0x50
-#define	WUM_EXEC	0x51
-
-#define WANPIPE		0x00
-#define API		0x01
-#define BRIDGE		0x02
-#define BRIDGE_NODE	0x03
-
-#ifdef	__KERNEL__
-/****** Kernel Interface ****************************************************/
-
-#include <linux/sdladrv.h>	/* SDLA support module API definitions */
-#include <linux/sdlasfm.h>	/* SDLA firmware module definitions */
-#include <linux/workqueue.h>
-#include <linux/serial.h>
-#include <linux/serialP.h>
-#include <linux/serial_reg.h>
-#include <asm/serial.h>
-#include <linux/tty.h>
-#include <linux/tty_driver.h>
-#include <linux/tty_flip.h>
-
-/****** Data Structures *****************************************************/
-
-/* Adapter Data Space.
- * This structure is needed because we handle multiple cards, otherwise
- * static data would do it.
- */
-typedef struct sdla
-{
-	char devname[WAN_DRVNAME_SZ+1];	/* card name */
-	sdlahw_t hw;			/* hardware configuration */
-	struct wan_device wandev;	/* WAN device data space */
-	
-	unsigned open_cnt;		/* number of open interfaces */
-	unsigned long state_tick;	/* link state timestamp */
-	unsigned intr_mode;		/* Type of Interrupt Mode */
-	char in_isr;			/* interrupt-in-service flag */
-	char buff_int_mode_unbusy;	/* flag for carrying out dev_tint */  
-	char dlci_int_mode_unbusy;	/* flag for carrying out dev_tint */
-	long configured;		/* flag for previous configurations */
-	
-	unsigned short irq_dis_if_send_count; /* Disabling irqs in if_send*/
-	unsigned short irq_dis_poll_count;   /* Disabling irqs in poll routine*/
-	unsigned short force_enable_irq;
-	char TracingEnabled;		/* flag for enabling trace */
-	global_stats_t statistics;	/* global statistics */
-	void* mbox;			/* -> mailbox */
-	void* rxmb;			/* -> receive mailbox */
-	void* flags;			/* -> adapter status flags */
-	void (*isr)(struct sdla* card);	/* interrupt service routine */
-	void (*poll)(struct sdla* card); /* polling routine */
-	int (*exec)(struct sdla* card, void* u_cmd, void* u_data);
-					/* Used by the listen() system call */		
-	/* Wanpipe Socket Interface */
-	int   (*func) (struct sk_buff *, struct sock *);
-	struct sock *sk;
-
-	/* Shutdown function */
-	void (*disable_comm) (struct sdla *card);
-
-	/* Secondary Port Device: Piggibacking */
-	struct sdla *next;
-
-	/* TTY driver variables */
-	unsigned char tty_opt;
-	struct tty_struct *tty;
-	unsigned int tty_minor;
-	unsigned int tty_open;
-	unsigned char *tty_buf;
-	unsigned char *tty_rx;
-	struct work_struct tty_work;
-	
-	union
-	{
-		struct
-		{			/****** X.25 specific data **********/
-			u32 lo_pvc;
-			u32 hi_pvc;
-			u32 lo_svc;
-			u32 hi_svc;
-			struct net_device *svc_to_dev_map[MAX_X25_LCN];
-			struct net_device *pvc_to_dev_map[MAX_X25_LCN];
-			struct net_device *tx_dev;
-			struct net_device *cmd_dev;
-			u32 no_dev;
-			volatile u8 *hdlc_buf_status;
-			u32 tx_interrupts_pending;
-                        u16 timer_int_enabled;
-			struct net_device *poll_device;
-			atomic_t command_busy;
-
-			u16 udp_pkt_lgth;
-                        u32 udp_type;
-                        u8  udp_pkt_src;
-			u32 udp_lcn;
-                        struct net_device *udp_dev;
-                        s8 udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
-
-		 	u8 LAPB_hdlc;		/* Option to turn off X25 and run only LAPB */
-			u8 logging;		/* Option to log call messages */
-			u8 oob_on_modem;	/* Option to send modem status to the api */
-			u16 num_of_ch;		/* Number of channels configured by the user */
-
-			struct work_struct x25_poll_work;
-			struct timer_list x25_timer;
-		} x;
-		struct
-		{			/****** frame relay specific data ***/
-			void* rxmb_base;	/* -> first Rx buffer */
-			void* rxmb_last;	/* -> last Rx buffer */
-			unsigned rx_base;	/* S508 receive buffer base */
-			unsigned rx_top;	/* S508 receive buffer end */
-			unsigned short node_dlci[100];
-			unsigned short dlci_num;
-                        struct net_device *dlci_to_dev_map[991 + 1];
-                        unsigned tx_interrupts_pending;
-                        unsigned short timer_int_enabled;
-                        unsigned short udp_pkt_lgth;
-                        int udp_type;
-                        char udp_pkt_src;
-                        unsigned udp_dlci;
-                        char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
-                        void* trc_el_base;      		/* first trace element */
-                        void* trc_el_last;      		/* last trace element */
-                        void *curr_trc_el;      		/* current trace element */
-                        unsigned short trc_bfr_space; 		/* trace buffer space */
-			unsigned char  update_comms_stats;
-			struct net_device *arp_dev;
-			spinlock_t if_send_lock;
-		} f;
-		struct			/****** PPP-specific data ***********/
-		{
-			char if_name[WAN_IFNAME_SZ+1];	/* interface name */
-			void* txbuf;		/* -> current Tx buffer */
-			void* txbuf_base;	/* -> first Tx buffer */
-			void* txbuf_last;	/* -> last Tx buffer */
-			void* rxbuf_base;	/* -> first Rx buffer */
-			void* rxbuf_last;	/* -> last Rx buffer */
-			unsigned rx_base;	/* S508 receive buffer base */
-			unsigned rx_top;	/* S508 receive buffer end */
-			char ip_mode;		/* STATIC/HOST/PEER IP Mode */
-			char authenticator;	/* Authenticator for PAP/CHAP */
-			unsigned char comm_enabled; /* Is comm enabled or not */
-			unsigned char peer_route;   /* Process Peer Route */	
-			unsigned long *txbuf_next;  /* Next Tx buffer to use */ 
-			unsigned long *rxbuf_next;  /* Next Rx buffer to use */
-		} p;
-		struct			/* Cisco HDLC-specific data */
-		{
-			char if_name[WAN_IFNAME_SZ+1];	/* interface name */
-			unsigned char comm_port;/* Communication Port O or 1 */
-			unsigned char usedby;  /* Used by WANPIPE or API */
-			void* rxmb;		/* Receive mail box */
-			void* flags;		/* flags */
-			void* tx_status;	/* Tx status element */
-			void* rx_status;	/* Rx status element */
-			void* txbuf;		/* -> current Tx buffer */
-			void* txbuf_base;	/* -> first Tx buffer */
-			void* txbuf_last;	/* -> last Tx buffer */
-			void* rxbuf_base;	/* -> first Rx buffer */
-			void* rxbuf_last;	/* -> last Rx buffer */
-			unsigned rx_base;	/* S508 receive buffer base */
-			unsigned rx_top;	/* S508 receive buffer end */
-			unsigned char receive_only; /* high speed receivers */
-			unsigned short protocol_options;
-			unsigned short kpalv_tx;	/* Tx kpalv timer */
-			unsigned short kpalv_rx;	/* Rx kpalv timer */
-			unsigned short kpalv_err;	/* Error tolerance */
-			unsigned short slarp_timer;	/* SLARP req timer */
-			unsigned state;			/* state of the link */
-			unsigned char api_status;
-			unsigned char update_call_count;
-			unsigned short api_options;	/* for async config */
-			unsigned char  async_mode;
-		        unsigned short tx_bits_per_char;
-		        unsigned short rx_bits_per_char;
-		        unsigned short stop_bits;
-		        unsigned short parity;
-			unsigned short break_timer;
-		        unsigned short inter_char_timer;
-		        unsigned short rx_complete_length;
-		        unsigned short xon_char;
-		        unsigned short xoff_char;
-			unsigned char comm_enabled; /* Is comm enabled or not */
-			unsigned char backup;
-		} c;
-		struct
-		{
-			void* tx_status;	/* Tx status element */
-			void* rx_status;	/* Rx status element */
-			void* trace_status;	/* Trace status element */
-			void* txbuf;		/* -> current Tx buffer */
-			void* txbuf_base;	/* -> first Tx buffer */
-			void* txbuf_last;	/* -> last Tx buffer */
-			void* rxbuf_base;	/* -> first Rx buffer */
-			void* rxbuf_last;	/* -> last Rx buffer */
-			void* tracebuf;		/* -> current Trace buffer */
-			void* tracebuf_base;	/* -> current Trace buffer */
-			void* tracebuf_last;	/* -> current Trace buffer */
-			unsigned rx_base;	/* receive buffer base */
-			unsigned rx_end;	/* receive buffer end */
-			unsigned trace_base;	/* trace buffer base */
-			unsigned trace_end;	/* trace buffer end */
-
-		} h;
-	} u;
-} sdla_t;
-
-/****** Public Functions ****************************************************/
-
-void wanpipe_open      (sdla_t* card);			/* wpmain.c */
-void wanpipe_close     (sdla_t* card);			/* wpmain.c */
-void wanpipe_set_state (sdla_t* card, int state);	/* wpmain.c */
-
-int wpx_init (sdla_t* card, wandev_conf_t* conf);	/* wpx.c */
-int wpf_init (sdla_t* card, wandev_conf_t* conf);	/* wpf.c */
-int wpp_init (sdla_t* card, wandev_conf_t* conf);	/* wpp.c */
-int wpc_init (sdla_t* card, wandev_conf_t* conf); /* Cisco HDLC */
-int bsc_init (sdla_t* card, wandev_conf_t* conf);	/* BSC streaming */
-int hdlc_init(sdla_t* card, wandev_conf_t* conf);	/* HDLC support */
-int wpft1_init (sdla_t* card, wandev_conf_t* conf);     /* FT1 Config support */
-int wsppp_init (sdla_t* card, wandev_conf_t* conf);	/* Sync PPP on top of RAW CHDLC */
-
-extern sdla_t * wanpipe_find_card(char *);
-extern sdla_t * wanpipe_find_card_num (int);
-
-extern void wanpipe_queue_work (struct work_struct *);
-extern void wanpipe_mark_bh (void);
-extern void wakeup_sk_bh(struct net_device *dev);
-extern int change_dev_flags(struct net_device *dev, unsigned flags);
-extern unsigned long get_ip_address(struct net_device *dev, int option);
-extern void add_gateway(sdla_t *card, struct net_device *dev);
-
-
-#endif	/* __KERNEL__ */
-#endif	/* _WANPIPE_H */
-
diff --git a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
index 8b9bf4a..b126518 100644
--- a/net/wanrouter/af_wanpipe.c
+++ b/net/wanrouter/af_wanpipe.c
@@ -55,12 +55,10 @@
 #include <asm/uaccess.h>
 #include <linux/module.h>
 #include <linux/init.h>
-#include <linux/wanpipe.h>
 #include <linux/if_wanpipe.h>
 #include <linux/pkt_sched.h>
 #include <linux/tcp_states.h>
 #include <linux/if_wanpipe_common.h>
-#include <linux/sdla_x25.h>
 
 #ifdef CONFIG_INET
 #include <net/inet_common.h>