]> err.no Git - linux-2.6/commitdiff
[WAN]: Remove broken and unmaintained Sangoma drivers.
authorAdrian Bunk <bunk@stusta.de>
Wed, 12 Apr 2006 00:28:33 +0000 (17:28 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 12 Apr 2006 00:28:33 +0000 (17:28 -0700)
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>
20 files changed:
MAINTAINERS
drivers/net/wan/Kconfig
drivers/net/wan/Makefile
drivers/net/wan/sdla_chdlc.c [deleted file]
drivers/net/wan/sdla_fr.c [deleted file]
drivers/net/wan/sdla_ft1.c [deleted file]
drivers/net/wan/sdla_ppp.c [deleted file]
drivers/net/wan/sdla_x25.c [deleted file]
drivers/net/wan/sdladrv.c [deleted file]
drivers/net/wan/sdlamain.c [deleted file]
drivers/net/wan/wanpipe_multppp.c [deleted file]
include/linux/sdla_asy.h [deleted file]
include/linux/sdla_chdlc.h [deleted file]
include/linux/sdla_ppp.h [deleted file]
include/linux/sdla_x25.h [deleted file]
include/linux/sdladrv.h [deleted file]
include/linux/sdlapci.h [deleted file]
include/linux/sdlasfm.h [deleted file]
include/linux/wanpipe.h [deleted file]
net/wanrouter/af_wanpipe.c

index d00dea52123f76d227b09ff8c18a166e5301540a..6d3c401ccdb6cb14e8b5c5248b7a99f1743cd109 100644 (file)
@@ -3058,13 +3058,6 @@ M:       khali@linux-fr.org
 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
index 883cf7da10fcb0f41ab9e4f5fd16626213f7a620..b5328b0ff927d6b063815a81aea7c388b2241e58 100644 (file)
@@ -410,103 +410,6 @@ config WAN_ROUTER_DRIVERS
 
          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)
index ce6c56b903e797b49e9de9c343a826533aa329eb..823c6d5ab90d8e0143ed2266d29e769bf04cd06c 100644 (file)
@@ -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_LANMEDIA)               += lmc/
 
 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 (file)
index 496d292..0000000
+++ /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 (file)
index 7f1ce9d..0000000
+++ /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 (file)
index 9d6528a..0000000
+++ /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 (file)
index a4b489c..0000000
+++ /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 (file)
index 63f846d..0000000
+++ /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 (file)
index 032c0f8..0000000
+++ /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 (file)
index 7a8b22a..0000000
+++ /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 (file)
index 812a118..0000000
+++ /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 (file)
index f622425..0000000
+++ /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 (file)
index d2e35a2..0000000
+++ /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 (file)
index 6f39231..0000000
+++ /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 (file)
index 57db980..0000000
+++ /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 (file)
index c85e103..0000000
+++ /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 (file)
index 6f7c904..0000000
+++ /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 (file)
index 94aaa8a..0000000
+++ /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 (file)
index dae9860..0000000
+++ /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 */
-
index 8b9bf4a763b55408e3449aa6a0aa4c2a6d80be4d..b1265187b4a8f8cfe4c55ec5aa3f36742f30c917 100644 (file)
 #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>