File: /usr/src/linux/drivers/net/wan/sdla_chdlc.c

1     /*****************************************************************************
2     * sdla_chdlc.c	WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module.
3     *
4     * Authors: 	Nenad Corbic <ncorbic@sangoma.com>
5     *		Gideon Hack  
6     *
7     * Copyright:	(c) 1995-2001 Sangoma Technologies Inc.
8     *
9     *		This program is free software; you can redistribute it and/or
10     *		modify it under the terms of the GNU General Public License
11     *		as published by the Free Software Foundation; either version
12     *		2 of the License, or (at your option) any later version.
13     * ============================================================================
14     * Feb 28, 2001  Nenad Corbic	Updated if_tx_timeout() routine for 
15     * 				2.4.X kernels.
16     * Jan 25, 2001  Nenad Corbic	Added a TTY Sync serial driver over the
17     * 				HDLC streaming protocol
18     * 				Added a TTY Async serial driver over the
19     * 				Async protocol.
20     * Dec 15, 2000  Nenad Corbic    Updated for 2.4.X Kernel support
21     * Nov 13, 2000  Nenad Corbic    Added true interface type encoding option.
22     * 				Tcpdump doesn't support CHDLC inteface
23     * 				types, to fix this "true type" option will set
24     * 				the interface type to RAW IP mode.
25     * Nov 07, 2000  Nenad Corbic	Added security features for UDP debugging:
26     *                               Deny all and specify allowed requests.
27     * Jun 20, 2000  Nenad Corbic	Fixed the API IP ERROR bug. Caused by the 
28     *                               latest update.
29     * May 09, 2000	Nenad Corbic	Option to bring down an interface
30     *                               upon disconnect.
31     * Mar 23, 2000  Nenad Corbic	Improved task queue, bh handling.
32     * Mar 16, 2000	Nenad Corbic	Fixed the SLARP Dynamic IP addressing.
33     * Mar 06, 2000  Nenad Corbic	Bug Fix: corrupted mbox recovery.
34     * Feb 10, 2000  Gideon Hack     Added ASYNC support.
35     * Feb 09, 2000  Nenad Corbic    Fixed two shutdown bugs in update() and
36     *                               if_stats() functions.
37     * Jan 24, 2000  Nenad Corbic    Fixed a startup wanpipe state racing,  
38     *                               condition between if_open and isr. 
39     * Jan 10, 2000  Nenad Corbic    Added new socket API support.
40     * Dev 15, 1999  Nenad Corbic    Fixed up header files for 2.0.X kernels
41     * Nov 20, 1999  Nenad Corbic 	Fixed zero length API bug.
42     * Sep 30, 1999  Nenad Corbic    Fixed dynamic IP and route setup.
43     * Sep 23, 1999  Nenad Corbic    Added SMP support, fixed tracing 
44     * Sep 13, 1999  Nenad Corbic	Split up Port 0 and 1 into separate devices.
45     * Jun 02, 1999  Gideon Hack     Added support for the S514 adapter.
46     * Oct 30, 1998	Jaspreet Singh	Added Support for CHDLC API (HDLC STREAMING).
47     * Oct 28, 1998	Jaspreet Singh	Added Support for Dual Port CHDLC.
48     * Aug 07, 1998	David Fong	Initial version.
49     *****************************************************************************/
50     
51     #include <linux/module.h>
52     #include <linux/version.h>
53     #include <linux/kernel.h>	/* printk(), and other useful stuff */
54     #include <linux/stddef.h>	/* offsetof(), etc. */
55     #include <linux/errno.h>	/* return codes */
56     #include <linux/string.h>	/* inline memset(), etc. */
57     #include <linux/slab.h>	/* kmalloc(), kfree() */
58     #include <linux/wanrouter.h>	/* WAN router definitions */
59     #include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
60     #include <linux/if_arp.h>	/* ARPHRD_* defines */
61     
62     
63     #if defined(LINUX_2_1) || defined(LINUX_2_4)
64      #include <asm/uaccess.h>
65      #include <linux/inetdevice.h>
66      #include <linux/netdevice.h>
67     #else 				
68      #include <asm/segment.h>
69      #include <net/route.h>          /* Adding new route entries : 2.0.X kernels */
70     #endif
71     
72     #include <linux/in.h>		/* sockaddr_in */
73     #include <linux/inet.h>	
74     #include <linux/if.h>
75     #include <asm/byteorder.h>	/* htons(), etc. */
76     #include <linux/sdlapci.h>
77     #include <asm/io.h>
78     
79     #include <linux/sdla_chdlc.h>		/* CHDLC firmware API definitions */
80     #include <linux/sdla_asy.h>           	/* CHDLC (async) API definitions */
81     
82     #include <linux/if_wanpipe_common.h>    /* Socket Driver common area */
83     #include <linux/if_wanpipe.h>		
84     
85     /* TTY Includes */
86     #include <linux/tty.h>
87     #include <linux/tty_flip.h>
88     #include <linux/serial.h>
89     
90     
91     /****** Defines & Macros ****************************************************/
92     
93     /* reasons for enabling the timer interrupt on the adapter */
94     #define TMR_INT_ENABLED_UDP   		0x01
95     #define TMR_INT_ENABLED_UPDATE		0x02
96     #define TMR_INT_ENABLED_CONFIG		0x10
97     
98     #define MAX_IP_ERRORS	10
99     
100     #define TTY_CHDLC_MAX_MTU	2000
101     #define	CHDLC_DFLT_DATA_LEN	1500		/* default MTU */
102     #define CHDLC_HDR_LEN		1
103     
104     #define CHDLC_API 0x01
105     
106     #define PORT(x)   (x == 0 ? "PRIMARY" : "SECONDARY" )
107     #define MAX_BH_BUFF	10
108     
109     //#define PRINT_DEBUG
110     #ifdef PRINT_DEBUG
111     #define dbg_printk(format, a...) printk(format, ## a)
112     #else
113     #define dbg_printk(format, a...)
114     #endif  
115     
116     /******Data Structures*****************************************************/
117     
118     /* This structure is placed in the private data area of the device structure.
119      * The card structure used to occupy the private area but now the following 
120      * structure will incorporate the card structure along with CHDLC specific data
121      */
122     
123     typedef struct chdlc_private_area
124     {
125     	wanpipe_common_t common;
126     	sdla_t		*card;
127     	int 		TracingEnabled;		/* For enabling Tracing */
128     	unsigned long 	curr_trace_addr;	/* Used for Tracing */
129     	unsigned long 	start_trace_addr;
130     	unsigned long 	end_trace_addr;
131     	unsigned long 	base_addr_trace_buffer;
132     	unsigned long 	end_addr_trace_buffer;
133     	unsigned short 	number_trace_elements;
134     	unsigned  	available_buffer_space;
135     	unsigned long 	router_start_time;
136     	unsigned char 	route_status;
137     	unsigned char 	route_removed;
138     	unsigned long 	tick_counter;		/* For 5s timeout counter */
139     	unsigned long 	router_up_time;
140             u32             IP_address;		/* IP addressing */
141             u32             IP_netmask;
142     	u32		ip_local;
143     	u32		ip_remote;
144     	u32 		ip_local_tmp;
145     	u32		ip_remote_tmp;
146     	u8		ip_error;
147     	u8		config_chdlc;
148     	u8 		config_chdlc_timeout;
149     	unsigned char  mc;			/* Mulitcast support on/off */
150     	unsigned short udp_pkt_lgth;		/* udp packet processing */
151     	char udp_pkt_src;
152     	char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
153     	unsigned short timer_int_enabled;
154     	char update_comms_stats;		/* updating comms stats */
155     
156     #if defined(LINUX_2_1) || defined(LINUX_2_4)
157     	bh_data_t *bh_head;	  	  /* Circular buffer for chdlc_bh */
158     	unsigned long  tq_working;
159     	volatile int  bh_write;
160     	volatile int  bh_read;
161     	atomic_t  bh_buff_used;
162     #endif
163     	
164     	unsigned char interface_down;
165     
166     	/* Polling task queue. Each interface
167              * has its own task queue, which is used
168              * to defer events from the interrupt */
169     	struct tq_struct poll_task;
170     	struct timer_list poll_delay_timer;
171     
172     	u8 gateway;
173     	u8 true_if_encoding;
174     	//FIXME: add driver stats as per frame relay!
175     
176     } chdlc_private_area_t;
177     
178     /* Route Status options */
179     #define NO_ROUTE	0x00
180     #define ADD_ROUTE	0x01
181     #define ROUTE_ADDED	0x02
182     #define REMOVE_ROUTE	0x03
183     
184     
185     /* variable for keeping track of enabling/disabling FT1 monitor status */
186     static int rCount = 0;
187     
188     /* variable for tracking how many interfaces to open for WANPIPE on the
189        two ports */
190     
191     extern void disable_irq(unsigned int);
192     extern void enable_irq(unsigned int);
193     
194     /****** Function Prototypes *************************************************/
195     /* WAN link driver entry points. These are called by the WAN router module. */
196     static int update (wan_device_t* wandev);
197     static int new_if (wan_device_t* wandev, netdevice_t* dev,
198     	wanif_conf_t* conf);
199     
200     /* Network device interface */
201     static int if_init   (netdevice_t* dev);
202     static int if_open   (netdevice_t* dev);
203     static int if_close  (netdevice_t* dev);
204     static int if_header (struct sk_buff* skb, netdevice_t* dev,
205     	unsigned short type, void* daddr, void* saddr, unsigned len);
206     
207     #if defined(LINUX_2_1) || defined(LINUX_2_4)
208       static int if_rebuild_hdr (struct sk_buff *skb);
209       static struct net_device_stats* if_stats (netdevice_t* dev);
210     
211     #else
212       static int if_rebuild_hdr (void* hdr, netdevice_t* dev, unsigned long raddr,
213             struct sk_buff* skb);
214       static struct enet_statistics* if_stats (netdevice_t* dev);
215     #endif
216       
217     static int if_send (struct sk_buff* skb, netdevice_t* dev);
218     
219     /* CHDLC Firmware interface functions */
220     static int chdlc_configure 	(sdla_t* card, void* data);
221     static int chdlc_comm_enable 	(sdla_t* card);
222     static int chdlc_read_version 	(sdla_t* card, char* str);
223     static int chdlc_set_intr_mode 	(sdla_t* card, unsigned mode);
224     static int chdlc_send (sdla_t* card, void* data, unsigned len);
225     static int chdlc_read_comm_err_stats (sdla_t* card);
226     static int chdlc_read_op_stats (sdla_t* card);
227     static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
228     
229     
230     static int chdlc_disable_comm_shutdown (sdla_t *card);
231     #ifdef LINUX_2_4
232       static void if_tx_timeout (netdevice_t *dev);
233     #endif
234     
235     /* Miscellaneous CHDLC Functions */
236     static int set_chdlc_config (sdla_t* card);
237     static void init_chdlc_tx_rx_buff( sdla_t* card);
238     static int process_chdlc_exception(sdla_t *card);
239     static int process_global_exception(sdla_t *card);
240     static int update_comms_stats(sdla_t* card,
241             chdlc_private_area_t* chdlc_priv_area);
242     static int configure_ip (sdla_t* card);
243     static int unconfigure_ip (sdla_t* card);
244     static void process_route(sdla_t *card);
245     static void port_set_state (sdla_t *card, int);
246     static int config_chdlc (sdla_t *card);
247     static void disable_comm (sdla_t *card);
248     
249     static void trigger_chdlc_poll (netdevice_t *);
250     static void chdlc_poll (netdevice_t *);
251     static void chdlc_poll_delay (unsigned long dev_ptr);
252     
253     
254     /* Miscellaneous asynchronous interface Functions */
255     static int set_asy_config (sdla_t* card);
256     static int asy_comm_enable (sdla_t* card);
257     
258     /* Interrupt handlers */
259     static void wpc_isr (sdla_t* card);
260     static void rx_intr (sdla_t* card);
261     static void timer_intr(sdla_t *);
262     
263     #if defined(LINUX_2_1) || defined(LINUX_2_4)
264       /* Bottom half handlers */
265       static void chdlc_bh (netdevice_t *);
266       static int chdlc_bh_cleanup (netdevice_t *);
267       static int bh_enqueue (netdevice_t *, struct sk_buff *);
268     #endif
269     
270     /* Miscellaneous functions */
271     static int chk_bcast_mcast_addr(sdla_t* card, netdevice_t* dev,
272     				struct sk_buff *skb);
273     static int reply_udp( unsigned char *data, unsigned int mbox_len );
274     static int intr_test( sdla_t* card);
275     static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
276     static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
277                                     struct sk_buff *skb, netdevice_t* dev,
278                                     chdlc_private_area_t* chdlc_priv_area);
279     static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev,  
280     				chdlc_private_area_t* chdlc_priv_area);
281     static unsigned short calc_checksum (char *, int);
282     static void s508_lock (sdla_t *card, unsigned long *smp_flags);
283     static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
284     
285     
286     static int  Intr_test_counter;
287     
288     /* TTY Global Definitions */
289     
290     #if defined(LINUX_2_4) || defined(LINUX_2_1)
291     
292     #define NR_PORTS 4
293     #define WAN_TTY_MAJOR 226
294     #define WAN_TTY_MINOR 0
295     
296     #define WAN_CARD(port) (tty_card_map[port])
297     #define MIN_PORT 0
298     #define MAX_PORT NR_PORTS-1 
299     
300     #define CRC_LENGTH 2
301     
302     static int wanpipe_tty_init(sdla_t *card);
303     static void wanpipe_tty_receive(sdla_t *, unsigned, unsigned int);
304     static void wanpipe_tty_trigger_poll(sdla_t *card);
305     
306     static struct tty_driver serial_driver, callout_driver;
307     static int serial_refcount=1;
308     static int tty_init_cnt=0;
309     
310     static struct serial_state rs_table[NR_PORTS];
311     static struct tty_struct *serial_table[NR_PORTS];
312     static struct termios *serial_termios[NR_PORTS];
313     static struct termios *serial_termios_locked[NR_PORTS];
314     
315     static char tty_driver_mode=WANOPT_TTY_SYNC;
316     
317     static char *opt_decode[] = {"NONE","CRTSCTS","XONXOFF-RX",
318     	  	             "CRTSCTS XONXOFF-RX","XONXOFF-TX",
319     		             "CRTSCTS XONXOFF-TX","CRTSCTS XONXOFF"};
320     static char *p_decode[] = {"NONE","ODD","EVEN"};
321     
322     static void* tty_card_map[NR_PORTS] = {NULL,NULL,NULL,NULL};
323     
324     #endif
325     
326     
327     /****** Public Functions ****************************************************/
328     
329     /*============================================================================
330      * Cisco HDLC protocol initialization routine.
331      *
332      * This routine is called by the main WANPIPE module during setup.  At this
333      * point adapter is completely initialized and firmware is running.
334      *  o read firmware version (to make sure it's alive)
335      *  o configure adapter
336      *  o initialize protocol-specific fields of the adapter data space.
337      *
338      * Return:	0	o.k.
339      *		< 0	failure.
340      */
341     int wpc_init (sdla_t* card, wandev_conf_t* conf)
342     {
343     	unsigned char port_num;
344     	int err;
345     	unsigned long max_permitted_baud = 0;
346     	SHARED_MEMORY_INFO_STRUCT *flags;
347     
348     	union
349     		{
350     		char str[80];
351     		} u;
352     	volatile CHDLC_MAILBOX_STRUCT* mb;
353     	CHDLC_MAILBOX_STRUCT* mb1;
354     	unsigned long timeout;
355     
356     	/* Verify configuration ID */
357     	if (conf->config_id != WANCONFIG_CHDLC) {
358     		printk(KERN_INFO "%s: invalid configuration ID %u!\n",
359     				  card->devname, conf->config_id);
360     		return -EINVAL;
361     	}
362     
363     	/* Find out which Port to use */
364     	if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
365     		if (card->next){
366     
367     			if (conf->comm_port != card->next->u.c.comm_port){
368     				card->u.c.comm_port = conf->comm_port;
369     			}else{
370     				printk(KERN_INFO "%s: ERROR - %s port used!\n",
371             		        	card->wandev.name, PORT(conf->comm_port));
372     				return -EINVAL;
373     			}
374     		}else{
375     			card->u.c.comm_port = conf->comm_port;
376     		}
377     	}else{
378     		printk(KERN_INFO "%s: ERROR - Invalid Port Selected!\n",
379                     			card->wandev.name);
380     		return -EINVAL;
381     	}
382     	
383     
384     	/* Initialize protocol-specific fields */
385     	if(card->hw.type != SDLA_S514){
386     
387     		if (card->u.c.comm_port == WANOPT_PRI){	
388     			card->mbox  = (void *) card->hw.dpmbase;
389     		}else{
390     			card->mbox  = (void *) card->hw.dpmbase + 
391     				SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
392     		}	
393     	}else{ 
394     		/* for a S514 adapter, set a pointer to the actual mailbox in the */
395     		/* allocated virtual memory area */
396     		if (card->u.c.comm_port == WANOPT_PRI){
397     			card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
398     		}else{
399     			card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
400     		}	
401     	}
402     
403     	mb = mb1 = card->mbox;
404     
405     	if (!card->configured){
406     
407     		/* The board will place an 'I' in the return code to indicate that it is
408     	   	ready to accept commands.  We expect this to be completed in less
409                	than 1 second. */
410     
411     		timeout = jiffies;
412     		while (mb->return_code != 'I')	/* Wait 1s for board to initialize */
413     			if ((jiffies - timeout) > 1*HZ) break;
414     
415     		if (mb->return_code != 'I') {
416     			printk(KERN_INFO
417     				"%s: Initialization not completed by adapter\n",
418     				card->devname);
419     			printk(KERN_INFO "Please contact Sangoma representative.\n");
420     			return -EIO;
421     		}
422     	}
423     
424     	/* Read firmware version.  Note that when adapter initializes, it
425     	 * clears the mailbox, so it may appear that the first command was
426     	 * executed successfully when in fact it was merely erased. To work
427     	 * around this, we execute the first command twice.
428     	 */
429     
430     	if (chdlc_read_version(card, u.str))
431     		return -EIO;
432     
433     	printk(KERN_INFO "%s: Running Cisco HDLC firmware v%s\n",
434     		card->devname, u.str); 
435     
436     	card->isr			= &wpc_isr;
437     	card->poll			= NULL;
438     	card->exec			= NULL;
439     	card->wandev.update		= &update;
440      	card->wandev.new_if		= &new_if;
441     	card->wandev.del_if		= NULL;
442     	card->wandev.udp_port   	= conf->udp_port;
443     	card->disable_comm		= &disable_comm;
444     	card->wandev.new_if_cnt = 0;
445     
446     	/* reset the number of times the 'update()' proc has been called */
447     	card->u.c.update_call_count = 0;
448     	
449     	card->wandev.ttl = conf->ttl;
450     	card->wandev.interface = conf->interface; 
451     
452     	if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
453     	    card->hw.type != SDLA_S514){
454     		printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n",
455     			card->devname, PORT(card->u.c.comm_port));
456     		return -EIO;
457     	}
458     
459     	card->wandev.clocking = conf->clocking;
460     
461     	port_num = card->u.c.comm_port;
462     
463     	/* in API mode, we can configure for "receive only" buffering */
464     	if(card->hw.type == SDLA_S514) {
465     		card->u.c.receive_only = conf->receive_only;
466     		if(conf->receive_only) {
467     			printk(KERN_INFO
468     				"%s: Configured for 'receive only' mode\n",
469                                     card->devname);
470     		}
471     	}
472     
473     	/* Setup Port Bps */
474     
475     	if(card->wandev.clocking) {
476     		if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
477     			/* For Primary Port 0 */
478                    		max_permitted_baud =
479     				(card->hw.type == SDLA_S514) ?
480     				PRI_MAX_BAUD_RATE_S514 : 
481     				PRI_MAX_BAUD_RATE_S508;
482     
483     		}else if(port_num == WANOPT_SEC) {
484     			/* For Secondary Port 1 */
485                             max_permitted_baud =
486                                    (card->hw.type == SDLA_S514) ?
487                                     SEC_MAX_BAUD_RATE_S514 :
488                                     SEC_MAX_BAUD_RATE_S508;
489                             }
490       
491     			if(conf->bps > max_permitted_baud) {
492     				conf->bps = max_permitted_baud;
493     				printk(KERN_INFO "%s: Baud too high!\n",
494     					card->wandev.name);
495      				printk(KERN_INFO "%s: Baud rate set to %lu bps\n", 
496     					card->wandev.name, max_permitted_baud);
497     			}
498     			card->wandev.bps = conf->bps;
499     	}else{
500             	card->wandev.bps = 0;
501       	}
502     
503     	/* Setup the Port MTU */
504     	if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
505     
506     		/* For Primary Port 0 */
507     		card->wandev.mtu =
508     			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
509     			min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
510     			CHDLC_DFLT_DATA_LEN;
511     	} else if(port_num == WANOPT_SEC) { 
512     		/* For Secondary Port 1 */
513     		card->wandev.mtu =
514     			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
515     			min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
516     			CHDLC_DFLT_DATA_LEN;
517     	}
518     
519     	/* Set up the interrupt status area */
520     	/* Read the CHDLC Configuration and obtain: 
521     	 *	Ptr to shared memory infor struct
522              * Use this pointer to calculate the value of card->u.c.flags !
523      	 */
524     	mb1->buffer_length = 0;
525     	mb1->command = READ_CHDLC_CONFIGURATION;
526     	err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
527     	if(err != COMMAND_OK) {
528                     if(card->hw.type != SDLA_S514)
529                     	enable_irq(card->hw.irq);
530     
531     		chdlc_error(card, err, mb1);
532     		return -EIO;
533     	}
534     
535     	if(card->hw.type == SDLA_S514){
536                    	card->u.c.flags = (void *)(card->hw.dpmbase +
537                    		(((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
538     			ptr_shared_mem_info_struct));
539             }else{
540                     card->u.c.flags = (void *)(card->hw.dpmbase +
541                             (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
542     			ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
543     	}
544     
545     	flags = card->u.c.flags;
546     	
547     	/* This is for the ports link state */
548     	card->wandev.state = WAN_DUALPORT;
549     	card->u.c.state = WAN_DISCONNECTED;
550     
551     
552     	if (!card->wandev.piggyback){	
553     		int err;
554     
555     		/* Perform interrupt testing */
556     		err = intr_test(card);
557     
558     		if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) { 
559     			printk(KERN_INFO "%s: Interrupt test failed (%i)\n",
560     					card->devname, Intr_test_counter);
561     			printk(KERN_INFO "%s: Please choose another interrupt\n",
562     					card->devname);
563     			return -EIO;
564     		}
565     		
566     		printk(KERN_INFO "%s: Interrupt test passed (%i)\n", 
567     				card->devname, Intr_test_counter);
568     		card->configured = 1;
569     	}
570     
571     	if ((card->tty_opt=conf->tty) == WANOPT_YES){
572     #if defined(LINUX_2_4) || defined(LINUX_2_1)	
573     		int err;
574     		card->tty_minor = conf->tty_minor;
575     
576     		/* On ASYNC connections internal clocking 
577     		 * is mandatory */
578     		if ((card->u.c.async_mode = conf->tty_mode)){
579     			card->wandev.clocking = 1;
580     		}
581     		err=wanpipe_tty_init(card);
582     		if (err){
583     			return err;
584     		}
585     #else
586     		printk(KERN_INFO "%s: Error: TTY driver is not supported on 2.0.X kernels!\n",
587     				card->devname);	
588     		return -EINVAL;  
589     #endif
590     	}else{
591     	
592     
593     		if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
594     			printk (KERN_INFO "%s: 
595     				Failed to set interrupt triggers!\n",
596     				card->devname);
597     			return -EIO;	
598             	}
599     	
600     		/* Mask the Timer interrupt */
601     		flags->interrupt_info_struct.interrupt_permission &= 
602     			~APP_INT_ON_TIMER;
603     	}
604     
605     	/* If we are using CHDLC in backup mode, this flag will
606     	 * indicate not to look for IP addresses in config_chdlc()*/
607     	card->u.c.backup = conf->backup;
608     	
609     	printk(KERN_INFO "\n");
610     
611     	return 0;
612     }
613     
614     /******* WAN Device Driver Entry Points *************************************/
615     
616     /*============================================================================
617      * Update device status & statistics
618      * This procedure is called when updating the PROC file system and returns
619      * various communications statistics. These statistics are accumulated from 3 
620      * different locations:
621      * 	1) The 'if_stats' recorded for the device.
622      * 	2) Communication error statistics on the adapter.
623      *      3) CHDLC operational statistics on the adapter.
624      * The board level statistics are read during a timer interrupt. Note that we 
625      * read the error and operational statistics during consecitive timer ticks so
626      * as to minimize the time that we are inside the interrupt handler.
627      *
628      */
629     static int update (wan_device_t* wandev)
630     {
631     	sdla_t* card = wandev->private;
632      	netdevice_t* dev;
633             volatile chdlc_private_area_t* chdlc_priv_area;
634             SHARED_MEMORY_INFO_STRUCT *flags;
635     	unsigned long timeout;
636     
637     	/* sanity checks */
638     	if((wandev == NULL) || (wandev->private == NULL))
639     		return -EFAULT;
640     	
641     	if(wandev->state == WAN_UNCONFIGURED)
642     		return -ENODEV;
643     
644     	/* more sanity checks */
645             if(!card->u.c.flags)
646                     return -ENODEV;
647     
648     	if(test_bit(PERI_CRIT, (void*)&card->wandev.critical))
649                     return -EAGAIN;
650     
651     	if((dev=card->wandev.dev) == NULL)
652     		return -ENODEV;
653     
654     	if((chdlc_priv_area=dev->priv) == NULL)
655     		return -ENODEV;
656     
657           	flags = card->u.c.flags;
658            	if(chdlc_priv_area->update_comms_stats){
659     		return -EAGAIN;
660     	}
661     			
662     	/* we will need 2 timer interrupts to complete the */
663     	/* reading of the statistics */
664     	chdlc_priv_area->update_comms_stats = 2;
665            	flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
666     	chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
667       
668     	/* wait a maximum of 1 second for the statistics to be updated */ 
669             timeout = jiffies;
670             for(;;) {
671     		if(chdlc_priv_area->update_comms_stats == 0)
672     			break;
673                     if ((jiffies - timeout) > (1 * HZ)){
674         			chdlc_priv_area->update_comms_stats = 0;
675      			chdlc_priv_area->timer_int_enabled &=
676     				~TMR_INT_ENABLED_UPDATE; 
677      			return -EAGAIN;
678     		}
679             }
680     
681     	return 0;
682     }
683     
684     
685     /*============================================================================
686      * Create new logical channel.
687      * This routine is called by the router when ROUTER_IFNEW IOCTL is being
688      * handled.
689      * o parse media- and hardware-specific configuration
690      * o make sure that a new channel can be created
691      * o allocate resources, if necessary
692      * o prepare network device structure for registaration.
693      *
694      * Return:	0	o.k.
695      *		< 0	failure (channel will not be created)
696      */
697     static int new_if (wan_device_t* wandev, netdevice_t* dev, wanif_conf_t* conf)
698     {
699     	sdla_t* card = wandev->private;
700     	chdlc_private_area_t* chdlc_priv_area;
701     
702     
703     	printk(KERN_INFO "%s: Configuring Interface: %s\n",
704     			card->devname, conf->name);
705      
706     	if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
707     		printk(KERN_INFO "%s: Invalid interface name!\n",
708     			card->devname);
709     		return -EINVAL;
710     	}
711     		
712     	/* allocate and initialize private data */
713     	chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
714     	
715     	if(chdlc_priv_area == NULL) 
716     		return -ENOMEM;
717     
718     	memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
719     
720     	chdlc_priv_area->card = card; 
721     	chdlc_priv_area->common.sk = NULL;
722     	chdlc_priv_area->common.func = NULL;	
723     
724     	/* initialize data */
725     	strcpy(card->u.c.if_name, conf->name);
726     
727     	if(card->wandev.new_if_cnt > 0) {
728                     kfree(chdlc_priv_area);
729     		return -EEXIST;
730     	}
731     
732     	card->wandev.new_if_cnt++;
733     
734     	chdlc_priv_area->TracingEnabled = 0;
735     	chdlc_priv_area->route_status = NO_ROUTE;
736     	chdlc_priv_area->route_removed = 0;
737     
738     	card->u.c.async_mode = conf->async_mode;
739     	
740     	/* setup for asynchronous mode */
741     	if(conf->async_mode) {
742     		printk(KERN_INFO "%s: Configuring for asynchronous mode\n",
743     			wandev->name);
744     
745     		if(card->u.c.comm_port == WANOPT_PRI) {
746     			printk(KERN_INFO
747     				"%s:Asynchronous mode on secondary port only\n",
748     					wandev->name);
749     			kfree(chdlc_priv_area);
750     			return -EINVAL;
751     		}
752     
753     	       	if(strcmp(conf->usedby, "WANPIPE") == 0) {
754     			printk(KERN_INFO
755                                     "%s: Running in WANIPE Async Mode\n",                                        			wandev->name);
756     			card->u.c.usedby = WANPIPE;
757     		}else{
758     			card->u.c.usedby = API;
759     		}
760     
761     		if(!card->wandev.clocking) {
762     			printk(KERN_INFO
763     				"%s: Asynch. clocking must be 'Internal'\n",
764     				wandev->name);
765     			kfree(chdlc_priv_area);
766     			return -EINVAL;
767     		}
768     
769     		if((card->wandev.bps < MIN_ASY_BAUD_RATE) ||
770     			(card->wandev.bps > MAX_ASY_BAUD_RATE)) {
771     			printk(KERN_INFO "%s: Selected baud rate is invalid.\n",
772     				wandev->name);
773     			printk(KERN_INFO "Must be between %u and %u bps.\n",
774     				MIN_ASY_BAUD_RATE, MAX_ASY_BAUD_RATE);
775     			kfree(chdlc_priv_area);
776     			return -EINVAL;
777     		}
778     
779     		card->u.c.api_options = 0;
780                     if (conf->asy_data_trans == WANOPT_YES) {
781                             card->u.c.api_options |= ASY_RX_DATA_TRANSPARENT;
782                     }
783     		
784     		card->u.c.protocol_options = 0;
785     		if (conf->rts_hs_for_receive == WANOPT_YES) {
786     			card->u.c.protocol_options |= ASY_RTS_HS_FOR_RX;
787     	        }
788                     if (conf->xon_xoff_hs_for_receive == WANOPT_YES) {
789                             card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_RX;
790                     }
791                     if (conf->xon_xoff_hs_for_transmit == WANOPT_YES) {
792                             card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_TX;
793                     }
794                     if (conf->dcd_hs_for_transmit == WANOPT_YES) {
795                             card->u.c.protocol_options |= ASY_DCD_HS_FOR_TX;
796                     }
797                     if (conf->cts_hs_for_transmit == WANOPT_YES) {
798                             card->u.c.protocol_options |= ASY_CTS_HS_FOR_TX;
799                     }
800     
801     		card->u.c.tx_bits_per_char = conf->tx_bits_per_char;
802                     card->u.c.rx_bits_per_char = conf->rx_bits_per_char;
803                     card->u.c.stop_bits = conf->stop_bits;
804     		card->u.c.parity = conf->parity;
805     		card->u.c.break_timer = conf->break_timer;
806     		card->u.c.inter_char_timer = conf->inter_char_timer;
807     		card->u.c.rx_complete_length = conf->rx_complete_length;
808     		card->u.c.xon_char = conf->xon_char;
809     
810     	} else {	/* setup for synchronous mode */
811     
812     		card->u.c.protocol_options = 0;
813     		if (conf->ignore_dcd == WANOPT_YES){
814     			card->u.c.protocol_options |= IGNORE_DCD_FOR_LINK_STAT;
815     		}
816     		if (conf->ignore_cts == WANOPT_YES){
817     			card->u.c.protocol_options |= IGNORE_CTS_FOR_LINK_STAT;
818     		}
819     
820     		if (conf->ignore_keepalive == WANOPT_YES) {
821     			card->u.c.protocol_options |=
822     				IGNORE_KPALV_FOR_LINK_STAT;
823     			card->u.c.kpalv_tx  = MIN_Tx_KPALV_TIMER; 
824     			card->u.c.kpalv_rx  = MIN_Rx_KPALV_TIMER; 
825     			card->u.c.kpalv_err = MIN_KPALV_ERR_TOL; 
826     
827     		} else {   /* Do not ignore keepalives */
828     			card->u.c.kpalv_tx =
829     				((conf->keepalive_tx_tmr - MIN_Tx_KPALV_TIMER)
830     				>= 0) ?
831     	   			min_t(unsigned int, conf->keepalive_tx_tmr,MAX_Tx_KPALV_TIMER) :
832     				DEFAULT_Tx_KPALV_TIMER;
833     
834     			card->u.c.kpalv_rx =
835     		   		((conf->keepalive_rx_tmr - MIN_Rx_KPALV_TIMER)
836     				>= 0) ?
837     	   			min_t(unsigned int, conf->keepalive_rx_tmr,MAX_Rx_KPALV_TIMER) :
838     				DEFAULT_Rx_KPALV_TIMER;
839     
840     			card->u.c.kpalv_err =
841     		   		((conf->keepalive_err_margin-MIN_KPALV_ERR_TOL)
842     				>= 0) ?
843     	   			min_t(unsigned int, conf->keepalive_err_margin,
844     				MAX_KPALV_ERR_TOL) : 
845     	   			DEFAULT_KPALV_ERR_TOL;
846     		}
847     
848     		/* Setup slarp timer to control delay between slarps */
849     		card->u.c.slarp_timer = 
850     			((conf->slarp_timer - MIN_SLARP_REQ_TIMER) >= 0) ?
851     			min_t(unsigned int, conf->slarp_timer, MAX_SLARP_REQ_TIMER) :
852     			DEFAULT_SLARP_REQ_TIMER;
853     
854     #ifdef LINUX_2_0
855     		if (card->u.c.slarp_timer){
856     			printk(KERN_INFO 
857     				"%s: Error: Dynamic IP support not available for 2.0.X kernels\n",
858     					card->devname);
859     			printk(KERN_INFO "%s:        Defaulting to Static IP addressing\n",
860     						card->devname);
861     		}
862     		card->u.c.slarp_timer=0;
863     #endif	
864     
865     
866     		if (conf->hdlc_streaming == WANOPT_YES) {
867     			printk(KERN_INFO "%s: Enabling HDLC STREAMING Mode\n",
868     				wandev->name);
869     			card->u.c.protocol_options = HDLC_STREAMING_MODE;
870     		}
871     
872     		if ((chdlc_priv_area->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){
873     			printk(KERN_INFO 
874     				"%s: Enabling, true interface type encoding.\n",
875     				card->devname);
876     		}
877     		
878             	/* Setup wanpipe as a router (WANPIPE) or as an API */
879     		if( strcmp(conf->usedby, "WANPIPE") == 0) {
880     
881     			printk(KERN_INFO "%s: Running in WANPIPE mode!\n",
882     				wandev->name);
883     			card->u.c.usedby = WANPIPE;
884     
885     			/* Option to bring down the interface when 
886             		 * the link goes down */
887     			if (conf->if_down){
888     				set_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down);
889     				printk(KERN_INFO 
890     				 "%s: Dynamic interface configuration enabled\n",
891     				   card->devname);
892     			} 
893     
894     		} else if( strcmp(conf->usedby, "API") == 0) {
895     #if defined(LINUX_2_1) || defined(LINUX_2_4) 
896     			card->u.c.usedby = API;
897     			printk(KERN_INFO "%s: Running in API mode !\n",
898     				wandev->name);
899     #else
900     			printk(KERN_INFO "%s: API Mode is not supported for kernels lower than 2.2.X!\n",
901     				wandev->name);
902     			printk(KERN_INFO "%s: Please upgrade to a 2.2.X kernel fro the API support\n",
903     				wandev->name);
904     	                kfree(chdlc_priv_area);
905     			return -EINVAL;
906     #endif
907     		}
908     	}
909     
910     #if defined(LINUX_2_1) || defined(LINUX_2_4)
911     	/* Tells us that if this interface is a
912              * gateway or not */
913     	if ((chdlc_priv_area->gateway = conf->gateway) == WANOPT_YES){
914     		printk(KERN_INFO "%s: Interface %s is set as a gateway.\n",
915     			card->devname,card->u.c.if_name);
916     	}
917     #endif
918     
919     	/* Get Multicast Information */
920     	chdlc_priv_area->mc = conf->mc;
921     
922     	/* prepare network device data space for registration */
923     #ifdef LINUX_2_4
924     	strcpy(dev->name,card->u.c.if_name);
925     #else
926     	dev->name = (char *)kmalloc(strlen(card->u.c.if_name) + 2, GFP_KERNEL); 
927     	sprintf(dev->name, "%s", card->u.c.if_name);
928     #endif
929     
930     	dev->init = &if_init;
931     	dev->priv = chdlc_priv_area;
932     
933     	/* Initialize the polling task routine */
934     #ifndef LINUX_2_4
935     	chdlc_priv_area->poll_task.next = NULL;
936     #endif
937     	chdlc_priv_area->poll_task.sync=0;
938     	chdlc_priv_area->poll_task.routine = (void*)(void*)chdlc_poll;
939     	chdlc_priv_area->poll_task.data = dev;
940     
941     	/* Initialize the polling delay timer */
942     	init_timer(&chdlc_priv_area->poll_delay_timer);
943     	chdlc_priv_area->poll_delay_timer.data = (unsigned long)dev;
944     	chdlc_priv_area->poll_delay_timer.function = chdlc_poll_delay;
945     	
946     	printk(KERN_INFO "\n");
947     
948     	return 0;
949     }
950     
951     
952     /****** Network Device Interface ********************************************/
953     
954     /*============================================================================
955      * Initialize Linux network interface.
956      *
957      * This routine is called only once for each interface, during Linux network
958      * interface registration.  Returning anything but zero will fail interface
959      * registration.
960      */
961     static int if_init (netdevice_t* dev)
962     	{
963     	chdlc_private_area_t* chdlc_priv_area = dev->priv;
964     	sdla_t* card = chdlc_priv_area->card;
965     	wan_device_t* wandev = &card->wandev;
966     #ifdef LINUX_2_0
967     	int i;
968     #endif
969     
970     	/* Initialize device driver entry points */
971     	dev->open		= &if_open;
972     	dev->stop		= &if_close;
973     	dev->hard_header	= &if_header;
974     	dev->rebuild_header	= &if_rebuild_hdr;
975     	dev->hard_start_xmit	= &if_send;
976     	dev->get_stats		= &if_stats;
977     #ifdef LINUX_2_4
978     	dev->tx_timeout		= &if_tx_timeout;
979     	dev->watchdog_timeo	= TX_TIMEOUT;
980     #endif
981     
982     	
983     	/* Initialize media-specific parameters */
984     	dev->flags		|= IFF_POINTOPOINT;
985     	dev->flags		|= IFF_NOARP;
986     
987     	/* Enable Mulitcasting if user selected */
988     	if (chdlc_priv_area->mc == WANOPT_YES){
989     		dev->flags 	|= IFF_MULTICAST;
990     	}
991     	
992     #ifdef LINUX_2_0
993     	dev->family		= AF_INET;
994     #endif	
995     
996     	if (chdlc_priv_area->true_if_encoding){
997     #if defined(LINUX_2_1) || defined(LINUX_2_4)
998     		dev->type	= ARPHRD_HDLC; /* This breaks the tcpdump */
999     #else
1000     		dev->type	= ARPHRD_PPP;
1001     #endif
1002     	}else{
1003     		dev->type	= ARPHRD_PPP;
1004     	}
1005     	
1006     	dev->mtu		= card->wandev.mtu;
1007     	/* for API usage, add the API header size to the requested MTU size */
1008     	if(card->u.c.usedby == API) {
1009     		dev->mtu += sizeof(api_tx_hdr_t);
1010     	}
1011      
1012     	dev->hard_header_len	= CHDLC_HDR_LEN;
1013     
1014     	/* Initialize hardware parameters */
1015     	dev->irq	= wandev->irq;
1016     	dev->dma	= wandev->dma;
1017     	dev->base_addr	= wandev->ioport;
1018     	dev->mem_start	= wandev->maddr;
1019     	dev->mem_end	= wandev->maddr + wandev->msize - 1;
1020     
1021     	/* Set transmit buffer queue length 
1022     	 * If too low packets will not be retransmitted 
1023              * by stack.
1024     	 */
1025             dev->tx_queue_len = 100;
1026        
1027     	/* Initialize socket buffers */
1028     #if !defined(LINUX_2_1) && !defined(LINUX_2_4)
1029             for (i = 0; i < DEV_NUMBUFFS; ++i)
1030                     skb_queue_head_init(&dev->buffs[i]);
1031     #endif
1032     	return 0;
1033     }
1034     
1035     /*============================================================================
1036      * Open network interface.
1037      * o enable communications and interrupts.
1038      * o prevent module from unloading by incrementing use count
1039      *
1040      * Return 0 if O.k. or errno.
1041      */
1042     static int if_open (netdevice_t* dev)
1043     {
1044     	chdlc_private_area_t* chdlc_priv_area = dev->priv;
1045     	sdla_t* card = chdlc_priv_area->card;
1046     	struct timeval tv;
1047     	int err = 0;
1048     
1049     	/* Only one open per interface is allowed */
1050     
1051     	if (is_dev_running(dev))
1052     		return -EBUSY;
1053     
1054     #if defined(LINUX_2_1) || defined(LINUX_2_4)
1055     	/* Initialize the task queue */
1056     	chdlc_priv_area->tq_working=0;
1057     
1058     #ifndef LINUX_2_4
1059     	chdlc_priv_area->common.wanpipe_task.next = NULL;
1060     #endif
1061     	chdlc_priv_area->common.wanpipe_task.sync = 0;
1062     	chdlc_priv_area->common.wanpipe_task.routine = (void *)(void *)chdlc_bh;
1063     	chdlc_priv_area->common.wanpipe_task.data = dev;
1064     
1065     	/* Allocate and initialize BH circular buffer */
1066     	/* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */
1067     	chdlc_priv_area->bh_head = kmalloc((sizeof(bh_data_t)*(MAX_BH_BUFF+1)),GFP_ATOMIC);
1068     	memset(chdlc_priv_area->bh_head,0,(sizeof(bh_data_t)*(MAX_BH_BUFF+1)));
1069     	atomic_set(&chdlc_priv_area->bh_buff_used, 0);
1070     #endif
1071      
1072     	do_gettimeofday(&tv);
1073     	chdlc_priv_area->router_start_time = tv.tv_sec;
1074     
1075     #ifdef LINUX_2_4
1076     	netif_start_queue(dev);
1077     #else
1078     	dev->interrupt = 0;
1079     	dev->tbusy = 0;
1080     	dev->start = 1;
1081     #endif
1082     
1083     	wanpipe_open(card);
1084     
1085     	/* TTY is configured during wanpipe_set_termios
1086     	 * call, not here */
1087     	if (card->tty_opt)
1088     		return err;
1089     	
1090     	set_bit(0,&chdlc_priv_area->config_chdlc);
1091     	chdlc_priv_area->config_chdlc_timeout=jiffies;
1092     	del_timer(&chdlc_priv_area->poll_delay_timer);
1093     
1094     	/* Start the CHDLC configuration after 1sec delay.
1095     	 * This will give the interface initilization time
1096     	 * to finish its configuration */
1097     	chdlc_priv_area->poll_delay_timer.expires=jiffies+HZ;
1098     	add_timer(&chdlc_priv_area->poll_delay_timer);
1099     	return err;
1100     }
1101     
1102     /*============================================================================
1103      * Close network interface.
1104      * o if this is the last close, then disable communications and interrupts.
1105      * o reset flags.
1106      */
1107     static int if_close (netdevice_t* dev)
1108     {
1109     	chdlc_private_area_t* chdlc_priv_area = dev->priv;
1110     	sdla_t* card = chdlc_priv_area->card;
1111     
1112     #if defined(LINUX_2_1) || defined(LINUX_2_4)
1113     
1114     	if (chdlc_priv_area->bh_head){
1115     		int i;
1116     		struct sk_buff *skb;
1117     	
1118     		for (i=0; i<(MAX_BH_BUFF+1); i++){
1119     			skb = ((bh_data_t *)&chdlc_priv_area->bh_head[i])->skb;
1120     			if (skb != NULL){
1121                     		wan_dev_kfree_skb(skb, FREE_READ);
1122     			}
1123     		}
1124     		kfree(chdlc_priv_area->bh_head);
1125     		chdlc_priv_area->bh_head=NULL;
1126     	}
1127     #endif
1128     
1129     	stop_net_queue(dev);
1130     #ifndef LINUX_2_4
1131     	dev->start=0;
1132     #endif
1133     	wanpipe_close(card);
1134     	del_timer(&chdlc_priv_area->poll_delay_timer);
1135     	return 0;
1136     }
1137     
1138     static void disable_comm (sdla_t *card)
1139     {
1140     	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1141     	
1142     	if (card->u.c.comm_enabled){
1143     		chdlc_disable_comm_shutdown (card);
1144     	}else{
1145     		flags->interrupt_info_struct.interrupt_permission = 0;	
1146     	}
1147     
1148     #if defined(LINUX_2_4) || defined(LINUX_2_1)	
1149     	if (!tty_init_cnt)
1150     		return;
1151     
1152     	if (card->tty_opt){
1153     		struct serial_state * state;
1154     		if (!(--tty_init_cnt)){
1155     			int e1,e2;
1156     			*serial_driver.refcount=0;
1157     			
1158     			if ((e1 = tty_unregister_driver(&serial_driver)))
1159     				printk("SERIAL: failed to unregister serial driver (%d)\n",
1160     				       e1);
1161     			if ((e2 = tty_unregister_driver(&callout_driver)))
1162     				printk("SERIAL: failed to unregister callout driver (%d)\n", 
1163     				       e2);
1164     			printk(KERN_INFO "%s: Unregistering TTY Driver, Major %i\n",
1165     					card->devname,WAN_TTY_MAJOR);
1166     		}
1167     		card->tty=NULL;
1168     		tty_card_map[card->tty_minor]=NULL;
1169     		state = &rs_table[card->tty_minor];
1170     		memset(state,0,sizeof(state));
1171     	}
1172     #endif
1173     	return;
1174     }
1175     
1176     
1177     /*============================================================================
1178      * Build media header.
1179      *
1180      * The trick here is to put packet type (Ethertype) into 'protocol' field of
1181      * the socket buffer, so that we don't forget it.  If packet type is not
1182      * supported, set skb->protocol to 0 and discard packet later.
1183      *
1184      * Return:	media header length.
1185      */
1186     static int if_header (struct sk_buff* skb, netdevice_t* dev,
1187     	unsigned short type, void* daddr, void* saddr, unsigned len)
1188     {
1189     	skb->protocol = htons(type);
1190     
1191     	return CHDLC_HDR_LEN;
1192     }
1193     
1194     
1195     #ifdef LINUX_2_4
1196     /*============================================================================
1197      * Handle transmit timeout event from netif watchdog
1198      */
1199     static void if_tx_timeout (netdevice_t *dev)
1200     {
1201         	chdlc_private_area_t* chan = dev->priv;
1202     	sdla_t *card = chan->card;
1203     	
1204     	/* If our device stays busy for at least 5 seconds then we will
1205     	 * kick start the device by making dev->tbusy = 0.  We expect
1206     	 * that our device never stays busy more than 5 seconds. So this                 
1207     	 * is only used as a last resort.
1208     	 */
1209     
1210     	++card->wandev.stats.collisions;
1211     
1212     	printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
1213     	netif_wake_queue (dev);
1214     }
1215     #endif
1216     
1217     
1218     
1219     /*============================================================================
1220      * Re-build media header.
1221      *
1222      * Return:	1	physical address resolved.
1223      *		0	physical address not resolved
1224      */
1225     #if defined(LINUX_2_1) || defined(LINUX_2_4)
1226     static int if_rebuild_hdr (struct sk_buff *skb)
1227     {
1228     	return 1;
1229     }
1230     #else
1231     static int if_rebuild_hdr (void* hdr, netdevice_t* dev, unsigned long raddr,
1232                                struct sk_buff* skb)
1233     {
1234             return 1;
1235     }
1236     #endif
1237     
1238     /*============================================================================
1239      * Send a packet on a network interface.
1240      * o set tbusy flag (marks start of the transmission) to block a timer-based
1241      *   transmit from overlapping.
1242      * o check link state. If link is not up, then drop the packet.
1243      * o execute adapter send command.
1244      * o free socket buffer
1245      *
1246      * Return:	0	complete (socket buffer must be freed)
1247      *		non-0	packet may be re-transmitted (tbusy must be set)
1248      *
1249      * Notes:
1250      * 1. This routine is called either by the protocol stack or by the "net
1251      *    bottom half" (with interrupts enabled).
1252      * 2. Setting tbusy flag will inhibit further transmit requests from the
1253      *    protocol stack and can be used for flow control with protocol layer.
1254      */
1255     static int if_send (struct sk_buff* skb, netdevice_t* dev)
1256     {
1257     	chdlc_private_area_t *chdlc_priv_area = dev->priv;
1258     	sdla_t *card = chdlc_priv_area->card;
1259     	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1260     	INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
1261     	int udp_type = 0;
1262     	unsigned long smp_flags;
1263     	int err=0;
1264     
1265     #ifdef LINUX_2_4
1266     	netif_stop_queue(dev);
1267     #endif
1268     	
1269     	if (skb == NULL){
1270     		/* If we get here, some higher layer thinks we've missed an
1271     		 * tx-done interrupt.
1272     		 */
1273     		printk(KERN_INFO "%s: interface %s got kicked!\n",
1274     			card->devname, dev->name);
1275     
1276     		wake_net_dev(dev);
1277     		return 0;
1278     	}
1279     
1280     #ifndef LINUX_2_4
1281     	if (dev->tbusy){
1282     
1283     		/* If our device stays busy for at least 5 seconds then we will
1284     		 * kick start the device by making dev->tbusy = 0.  We expect 
1285     		 * that our device never stays busy more than 5 seconds. So this
1286     		 * is only used as a last resort. 
1287     		 */
1288                     ++card->wandev.stats.collisions;
1289     		if((jiffies - chdlc_priv_area->tick_counter) < (5 * HZ)) {
1290     			return 1;
1291     		}
1292     
1293     		printk (KERN_INFO "%s: Transmit timeout !\n",
1294     			card->devname);
1295     
1296     		/* unbusy the interface */
1297     		clear_bit(0,&dev->tbusy);
1298     	}
1299     #endif
1300     
1301        	if (ntohs(skb->protocol) != htons(PVC_PROT)){
1302     
1303     		/* check the udp packet type */
1304     		
1305     		udp_type = udp_pkt_type(skb, card);
1306     
1307     		if (udp_type == UDP_CPIPE_TYPE){
1308                             if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
1309                                     chdlc_priv_area)){
1310     	                	chdlc_int->interrupt_permission |=
1311     					APP_INT_ON_TIMER;
1312     			}
1313     			start_net_queue(dev);
1314     			return 0;
1315     		}
1316     
1317     		/* check to see if the source IP address is a broadcast or */
1318     		/* multicast IP address */
1319                     if(chk_bcast_mcast_addr(card, dev, skb)){
1320     			++card->wandev.stats.tx_dropped;
1321     			wan_dev_kfree_skb(skb,FREE_WRITE);
1322     			start_net_queue(dev);
1323     			return 0;
1324     		}
1325             }
1326     
1327     	/* Lock the 508 Card: SMP is supported */
1328           	if(card->hw.type != SDLA_S514){
1329     		s508_lock(card,&smp_flags);
1330     	} 
1331     
1332         	if(test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
1333     	
1334     		printk(KERN_INFO "%s: Critical in if_send: %lx\n",
1335     					card->wandev.name,card->wandev.critical);
1336                     ++card->wandev.stats.tx_dropped;
1337     		start_net_queue(dev);
1338     		goto if_send_exit_crit;
1339     	}
1340     
1341     	if(card->u.c.state != WAN_CONNECTED){
1342            		++card->wandev.stats.tx_dropped;
1343     		start_net_queue(dev);
1344     		
1345     	}else if(!skb->protocol){
1346             	++card->wandev.stats.tx_errors;
1347     		start_net_queue(dev);
1348     		
1349     	}else {
1350     		void* data = skb->data;
1351     		unsigned len = skb->len;
1352     		unsigned char attr;
1353     
1354     		/* If it's an API packet pull off the API
1355     		 * header. Also check that the packet size
1356     		 * is larger than the API header
1357     	         */
1358     		if (card->u.c.usedby == API){
1359     			api_tx_hdr_t* api_tx_hdr;
1360     
1361     			/* discard the frame if we are configured for */
1362     			/* 'receive only' mode or if there is no data */
1363     			if (card->u.c.receive_only ||
1364     				(len <= sizeof(api_tx_hdr_t))) {
1365     				
1366     				++card->wandev.stats.tx_dropped;
1367     				start_net_queue(dev);
1368     				goto if_send_exit_crit;
1369     			}
1370     				
1371     			api_tx_hdr = (api_tx_hdr_t *)data;
1372     			attr = api_tx_hdr->attr;
1373     			data += sizeof(api_tx_hdr_t);
1374     			len -= sizeof(api_tx_hdr_t);
1375     		}
1376     
1377     		if(chdlc_send(card, data, len)) {
1378     			stop_net_queue(dev);
1379     		}else{
1380     			++card->wandev.stats.tx_packets;
1381     #if defined(LINUX_2_1) || defined(LINUX_2_4)
1382                             card->wandev.stats.tx_bytes += len;
1383     #endif
1384     			
1385     			start_net_queue(dev);
1386     			
1387     #ifdef LINUX_2_4
1388     		 	dev->trans_start = jiffies;
1389     #endif
1390     		}	
1391     	}
1392     
1393     if_send_exit_crit:
1394     	
1395     	if (!(err=is_queue_stopped(dev))) {
1396     		wan_dev_kfree_skb(skb, FREE_WRITE);
1397     	}else{
1398     		chdlc_priv_area->tick_counter = jiffies;
1399     		chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
1400     	}
1401     
1402     	clear_bit(SEND_CRIT, (void*)&card->wandev.critical);
1403     	if(card->hw.type != SDLA_S514){
1404     		s508_unlock(card,&smp_flags);
1405     	}
1406     	
1407     	return err;
1408     }
1409     
1410     
1411     /*============================================================================
1412      * Check to see if the packet to be transmitted contains a broadcast or
1413      * multicast source IP address.
1414      */
1415     
1416     static int chk_bcast_mcast_addr(sdla_t *card, netdevice_t* dev,
1417     				struct sk_buff *skb)
1418     {
1419     	u32 src_ip_addr;
1420             u32 broadcast_ip_addr = 0;
1421     #if defined(LINUX_2_1) || defined(LINUX_2_4)
1422             struct in_device *in_dev;
1423     #endif
1424             /* read the IP source address from the outgoing packet */
1425             src_ip_addr = *(u32 *)(skb->data + 12);
1426     
1427     	/* read the IP broadcast address for the device */
1428     #if defined(LINUX_2_1) || defined(LINUX_2_4)
1429             in_dev = dev->ip_ptr;
1430             if(in_dev != NULL) {
1431                     struct in_ifaddr *ifa= in_dev->ifa_list;
1432                     if(ifa != NULL)
1433                             broadcast_ip_addr = ifa->ifa_broadcast;
1434                     else
1435                             return 0;
1436             }
1437     #else
1438             broadcast_ip_addr = dev->pa_brdaddr;
1439     #endif
1440      
1441             /* check if the IP Source Address is a Broadcast address */
1442             if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {
1443                     printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n",
1444     				card->devname);
1445                     return 1;
1446             } 
1447     
1448             /* check if the IP Source Address is a Multicast address */
1449             if((ntohl(src_ip_addr) >= 0xE0000001) &&
1450     		(ntohl(src_ip_addr) <= 0xFFFFFFFE)) {
1451                     printk(KERN_INFO "%s: Multicast Source Address silently discarded\n",
1452     				card->devname);
1453                     return 1;
1454             }
1455     
1456             return 0;
1457     }
1458     
1459     
1460     /*============================================================================
1461      * Reply to UDP Management system.
1462      * Return length of reply.
1463      */
1464     static int reply_udp( unsigned char *data, unsigned int mbox_len )
1465     {
1466     
1467     	unsigned short len, udp_length, temp, ip_length;
1468     	unsigned long ip_temp;
1469     	int even_bound = 0;
1470       	chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data;
1471     	 
1472     	/* Set length of packet */
1473     	len = sizeof(ip_pkt_t)+ 
1474     	      sizeof(udp_pkt_t)+
1475     	      sizeof(wp_mgmt_t)+
1476     	      sizeof(cblock_t)+
1477     	      sizeof(trace_info_t)+ 
1478     	      mbox_len;
1479     
1480     	/* fill in UDP reply */
1481     	c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
1482        
1483     	/* fill in UDP length */
1484     	udp_length = sizeof(udp_pkt_t)+ 
1485     		     sizeof(wp_mgmt_t)+
1486     		     sizeof(cblock_t)+
1487     	             sizeof(trace_info_t)+
1488     		     mbox_len; 
1489     
1490      	/* put it on an even boundary */
1491     	if ( udp_length & 0x0001 ) {
1492     		udp_length += 1;
1493     		len += 1;
1494     		even_bound = 1;
1495     	}  
1496     
1497     	temp = (udp_length<<8)|(udp_length>>8);
1498     	c_udp_pkt->udp_pkt.udp_length = temp;
1499     		 
1500     	/* swap UDP ports */
1501     	temp = c_udp_pkt->udp_pkt.udp_src_port;
1502     	c_udp_pkt->udp_pkt.udp_src_port = 
1503     			c_udp_pkt->udp_pkt.udp_dst_port; 
1504     	c_udp_pkt->udp_pkt.udp_dst_port = temp;
1505     
1506     	/* add UDP pseudo header */
1507     	temp = 0x1100;
1508     	*((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp;	
1509     	temp = (udp_length<<8)|(udp_length>>8);
1510     	*((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp;
1511     
1512     		 
1513     	/* calculate UDP checksum */
1514     	c_udp_pkt->udp_pkt.udp_checksum = 0;
1515     	c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
1516     
1517     	/* fill in IP length */
1518     	ip_length = len;
1519     	temp = (ip_length<<8)|(ip_length>>8);
1520     	c_udp_pkt->ip_pkt.total_length = temp;
1521       
1522     	/* swap IP addresses */
1523     	ip_temp = c_udp_pkt->ip_pkt.ip_src_address;
1524     	c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address;
1525     	c_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
1526     
1527     	/* fill in IP checksum */
1528     	c_udp_pkt->ip_pkt.hdr_checksum = 0;
1529     	c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));
1530     
1531     	return len;
1532     
1533     } /* reply_udp */
1534     
1535     unsigned short calc_checksum (char *data, int len)
1536     {
1537     	unsigned short temp; 
1538     	unsigned long sum=0;
1539     	int i;
1540     
1541     	for( i = 0; i <len; i+=2 ) {
1542     		memcpy(&temp,&data[i],2);
1543     		sum += (unsigned long)temp;
1544     	}
1545     
1546     	while (sum >> 16 ) {
1547     		sum = (sum & 0xffffUL) + (sum >> 16);
1548     	}
1549     
1550     	temp = (unsigned short)sum;
1551     	temp = ~temp;
1552     
1553     	if( temp == 0 ) 
1554     		temp = 0xffff;
1555     
1556     	return temp;	
1557     }
1558     
1559     
1560     /*============================================================================
1561      * Get ethernet-style interface statistics.
1562      * Return a pointer to struct enet_statistics.
1563      */
1564     #if defined(LINUX_2_1) || defined(LINUX_2_4)
1565     static struct net_device_stats* if_stats (netdevice_t* dev)
1566     {
1567     	sdla_t *my_card;
1568     	chdlc_private_area_t* chdlc_priv_area;
1569     
1570     	if ((chdlc_priv_area=dev->priv) == NULL)
1571     		return NULL;
1572     
1573     	my_card = chdlc_priv_area->card;
1574     	return &my_card->wandev.stats; 
1575     }
1576     #else
1577     static struct enet_statistics* if_stats (netdevice_t* dev)
1578     {
1579             sdla_t *my_card;
1580             chdlc_private_area_t* chdlc_priv_area = dev->priv;
1581     
1582     	if ((chdlc_priv_area=dev->priv) == NULL)
1583     		return NULL;
1584     
1585             my_card = chdlc_priv_area->card;
1586             return &my_card->wandev.stats;
1587     }
1588     #endif
1589     
1590     /****** Cisco HDLC Firmware Interface Functions *******************************/
1591     
1592     /*============================================================================
1593      * Read firmware code version.
1594      *	Put code version as ASCII string in str. 
1595      */
1596     static int chdlc_read_version (sdla_t* card, char* str)
1597     {
1598     	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1599     	int len;
1600     	char err;
1601     	mb->buffer_length = 0;
1602     	mb->command = READ_CHDLC_CODE_VERSION;
1603     	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1604     
1605     	if(err != COMMAND_OK) {
1606     		chdlc_error(card,err,mb);
1607     	}
1608     	else if (str) {  /* is not null */
1609     		len = mb->buffer_length;
1610     		memcpy(str, mb->data, len);
1611     		str[len] = '\0';
1612     	}
1613     	return (err);
1614     }
1615     
1616     /*-----------------------------------------------------------------------------
1617      *  Configure CHDLC firmware.
1618      */
1619     static int chdlc_configure (sdla_t* card, void* data)
1620     {
1621     	int err;
1622     	CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
1623     	int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);
1624     	
1625     	mailbox->buffer_length = data_length;  
1626     	memcpy(mailbox->data, data, data_length);
1627     	mailbox->command = SET_CHDLC_CONFIGURATION;
1628     	err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
1629     	
1630     	if (err != COMMAND_OK) chdlc_error (card, err, mailbox);
1631                                
1632     	return err;
1633     }
1634     
1635     
1636     /*============================================================================
1637      * Set interrupt mode -- HDLC Version.
1638      */
1639     
1640     static int chdlc_set_intr_mode (sdla_t* card, unsigned mode)
1641     {
1642     	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1643     	CHDLC_INT_TRIGGERS_STRUCT* int_data =
1644     		 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1645     	int err;
1646     
1647     	int_data->CHDLC_interrupt_triggers 	= mode;
1648     	int_data->IRQ				= card->hw.irq;
1649     	int_data->interrupt_timer               = 1;
1650        
1651     	mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
1652     	mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
1653     	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1654     	if (err != COMMAND_OK)
1655     		chdlc_error (card, err, mb);
1656     	return err;
1657     }
1658     
1659     
1660     /*===========================================================
1661      * chdlc_disable_comm_shutdown
1662      *
1663      * Shutdown() disables the communications. We must
1664      * have a sparate functions, because we must not
1665      * call chdlc_error() hander since the private
1666      * area has already been replaced */
1667     
1668     static int chdlc_disable_comm_shutdown (sdla_t *card)
1669     {
1670     	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1671     	CHDLC_INT_TRIGGERS_STRUCT* int_data =
1672     		 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1673     	int err;
1674     
1675     	/* Disable Interrutps */
1676     	int_data->CHDLC_interrupt_triggers 	= 0;
1677     	int_data->IRQ				= card->hw.irq;
1678     	int_data->interrupt_timer               = 1;
1679        
1680     	mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
1681     	mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
1682     	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1683     
1684     	/* Disable Communications */
1685     
1686     	if (card->u.c.async_mode) {
1687     		mb->command = DISABLE_ASY_COMMUNICATIONS;
1688     	}else{
1689     		mb->command = DISABLE_CHDLC_COMMUNICATIONS;
1690     	}
1691     	
1692     	mb->buffer_length = 0;
1693     	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1694     	
1695     	card->u.c.comm_enabled = 0;
1696     	
1697     	return 0;
1698     }
1699     
1700     /*============================================================================
1701      * Enable communications.
1702      */
1703     
1704     static int chdlc_comm_enable (sdla_t* card)
1705     {
1706     	int err;
1707     	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1708     
1709     	mb->buffer_length = 0;
1710     	mb->command = ENABLE_CHDLC_COMMUNICATIONS;
1711     	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1712     	if (err != COMMAND_OK)
1713     		chdlc_error(card, err, mb);
1714     	else
1715     		card->u.c.comm_enabled = 1;
1716     	
1717     	return err;
1718     }
1719     
1720     /*============================================================================
1721      * Read communication error statistics.
1722      */
1723     static int chdlc_read_comm_err_stats (sdla_t* card)
1724     {
1725             int err;
1726             CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1727     
1728             mb->buffer_length = 0;
1729             mb->command = READ_COMMS_ERROR_STATS;
1730             err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1731             if (err != COMMAND_OK)
1732                     chdlc_error(card,err,mb);
1733             return err;
1734     }
1735     
1736     
1737     /*============================================================================
1738      * Read CHDLC operational statistics.
1739      */
1740     static int chdlc_read_op_stats (sdla_t* card)
1741     {
1742             int err;
1743             CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1744     
1745             mb->buffer_length = 0;
1746             mb->command = READ_CHDLC_OPERATIONAL_STATS;
1747             err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1748             if (err != COMMAND_OK)
1749                     chdlc_error(card,err,mb);
1750             return err;
1751     }
1752     
1753     
1754     /*============================================================================
1755      * Update communications error and general packet statistics.
1756      */
1757     static int update_comms_stats(sdla_t* card,
1758     	chdlc_private_area_t* chdlc_priv_area)
1759     {
1760             CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1761       	COMMS_ERROR_STATS_STRUCT* err_stats;
1762             CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;
1763     
1764     	/* on the first timer interrupt, read the comms error statistics */
1765     	if(chdlc_priv_area->update_comms_stats == 2) {
1766     		if(chdlc_read_comm_err_stats(card))
1767     			return 1;
1768     		err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data;
1769     		card->wandev.stats.rx_over_errors = 
1770     				err_stats->Rx_overrun_err_count;
1771     		card->wandev.stats.rx_crc_errors = 
1772     				err_stats->CRC_err_count;
1773     		card->wandev.stats.rx_frame_errors = 
1774     				err_stats->Rx_abort_count;
1775     		card->wandev.stats.rx_fifo_errors = 
1776     				err_stats->Rx_dis_pri_bfrs_full_count; 
1777     		card->wandev.stats.rx_missed_errors =
1778     				card->wandev.stats.rx_fifo_errors;
1779     		card->wandev.stats.tx_aborted_errors =
1780     				err_stats->sec_Tx_abort_count;
1781     	}
1782     
1783             /* on the second timer interrupt, read the operational statistics */
1784     	else {
1785             	if(chdlc_read_op_stats(card))
1786                     	return 1;
1787     		op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data;
1788     		card->wandev.stats.rx_length_errors =
1789     			(op_stats->Rx_Data_discard_short_count +
1790     			op_stats->Rx_Data_discard_long_count);
1791     	}
1792     
1793     	return 0;
1794     }
1795     
1796     /*============================================================================
1797      * Send packet.
1798      *	Return:	0 - o.k.
1799      *		1 - no transmit buffers available
1800      */
1801     static int chdlc_send (sdla_t* card, void* data, unsigned len)
1802     {
1803     	CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;
1804     
1805     	if (txbuf->opp_flag)
1806     		return 1;
1807     	
1808     	sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);
1809     
1810     	txbuf->frame_length = len;
1811     	txbuf->opp_flag = 1;		/* start transmission */
1812     	
1813     	/* Update transmit buffer control fields */
1814     	card->u.c.txbuf = ++txbuf;
1815     	
1816     	if ((void*)txbuf > card->u.c.txbuf_last)
1817     		card->u.c.txbuf = card->u.c.txbuf_base;
1818     	
1819     	return 0;
1820     }
1821     
1822     /****** Firmware Error Handler **********************************************/
1823     
1824     /*============================================================================
1825      * Firmware error handler.
1826      *	This routine is called whenever firmware command returns non-zero
1827      *	return code.
1828      *
1829      * Return zero if previous command has to be cancelled.
1830      */
1831     static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
1832     {
1833     	unsigned cmd = mb->command;
1834     
1835     	switch (err) {
1836     
1837     	case CMD_TIMEOUT:
1838     		printk(KERN_INFO "%s: command 0x%02X timed out!\n",
1839     			card->devname, cmd);
1840     		break;
1841     
1842     	case S514_BOTH_PORTS_SAME_CLK_MODE:
1843     		if(cmd == SET_CHDLC_CONFIGURATION) {
1844     			printk(KERN_INFO
1845     			 "%s: Configure both ports for the same clock source\n",
1846     				card->devname);
1847     			break;
1848     		}
1849     
1850     	default:
1851     		printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
1852     			card->devname, cmd, err);
1853     	}
1854     
1855     	return 0;
1856     }
1857     
1858     #if defined(LINUX_2_1) || defined(LINUX_2_4)
1859     /********** Bottom Half Handlers ********************************************/
1860     
1861     /* NOTE: There is no API, BH support for Kernels lower than 2.2.X.
1862      *       DO NOT INSERT ANY CODE HERE, NOTICE THE 
1863      *       PREPROCESSOR STATEMENT ABOVE, UNLESS YOU KNOW WHAT YOU ARE
1864      *       DOING */
1865     
1866     static void chdlc_bh (netdevice_t * dev)
1867     {
1868     	chdlc_private_area_t* chan = dev->priv;
1869     	sdla_t *card = chan->card;
1870     	struct sk_buff *skb;
1871     
1872     	if (atomic_read(&chan->bh_buff_used) == 0){
1873     		clear_bit(0, &chan->tq_working);
1874     		return;
1875     	}
1876     
1877     	while (atomic_read(&chan->bh_buff_used)){
1878     
1879     		skb  = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb;
1880     
1881     		if (skb != NULL){
1882     
1883     			if (chan->common.sk == NULL || chan->common.func == NULL){
1884     				++card->wandev.stats.rx_dropped;
1885     				wan_dev_kfree_skb(skb, FREE_READ);
1886     				chdlc_bh_cleanup(dev);
1887     				continue;
1888     			}
1889     
1890     			if (chan->common.func(skb,dev,chan->common.sk) != 0){
1891     				/* Sock full cannot send, queue us for another
1892                                      * try */
1893     				atomic_set(&chan->common.receive_block,1);
1894     				return;
1895     			}else{
1896     				chdlc_bh_cleanup(dev);
1897     			}
1898     		}else{
1899     			chdlc_bh_cleanup(dev);
1900     		}
1901     	}	
1902     	clear_bit(0, &chan->tq_working);
1903     
1904     	return;
1905     }
1906     
1907     static int chdlc_bh_cleanup (netdevice_t *dev)
1908     {
1909     	chdlc_private_area_t* chan = dev->priv;
1910     
1911     	((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL;
1912     
1913     	if (chan->bh_read == MAX_BH_BUFF){
1914     		chan->bh_read=0;
1915     	}else{
1916     		++chan->bh_read;	
1917     	}
1918     
1919     	atomic_dec(&chan->bh_buff_used);
1920     	return 0;
1921     }
1922     
1923     
1924     
1925     static int bh_enqueue (netdevice_t *dev, struct sk_buff *skb)
1926     {
1927     	/* Check for full */
1928     	chdlc_private_area_t* chan = dev->priv;
1929     	sdla_t *card = chan->card;
1930     
1931     	if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){
1932     		++card->wandev.stats.rx_dropped;
1933     		wan_dev_kfree_skb(skb, FREE_READ);
1934     		return 1; 
1935     	}
1936     
1937     	((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb;
1938     
1939     	if (chan->bh_write == MAX_BH_BUFF){
1940     		chan->bh_write=0;
1941     	}else{
1942     		++chan->bh_write;
1943     	}
1944     
1945     	atomic_inc(&chan->bh_buff_used);
1946     
1947     	return 0;
1948     }
1949     
1950     /* END OF API BH Support */
1951     
1952     #endif
1953     
1954     /****** Interrupt Handlers **************************************************/
1955     
1956     /*============================================================================
1957      * Cisco HDLC interrupt service routine.
1958      */
1959     static void wpc_isr (sdla_t* card)
1960     {
1961     	netdevice_t* dev;
1962     	SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1963     	int i;
1964     	sdla_t *my_card;
1965     
1966     
1967     	/* Check for which port the interrupt has been generated
1968     	 * Since Secondary Port is piggybacking on the Primary
1969              * the check must be done here. 
1970     	 */
1971     
1972     	flags = card->u.c.flags;
1973     	if (!flags->interrupt_info_struct.interrupt_type){
1974     		/* Check for a second port (piggybacking) */
1975     		if ((my_card = card->next)){
1976     			flags = my_card->u.c.flags;
1977     			if (flags->interrupt_info_struct.interrupt_type){
1978     				card = my_card;
1979     				card->isr(card);
1980     				return;
1981     			}
1982     		}
1983     	}
1984     
1985     	flags = card->u.c.flags;
1986     	card->in_isr = 1;
1987     	dev = card->wandev.dev;
1988     	
1989     	/* If we get an interrupt with no network device, stop the interrupts
1990     	 * and issue an error */
1991     	if (!card->tty_opt && !dev && 
1992     	    flags->interrupt_info_struct.interrupt_type != 
1993     	    	COMMAND_COMPLETE_APP_INT_PEND){
1994     
1995     		goto isr_done;
1996     	}
1997     	
1998     	/* if critical due to peripheral operations
1999     	 * ie. update() or getstats() then reset the interrupt and
2000     	 * wait for the board to retrigger.
2001     	 */
2002     	if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
2003     		printk(KERN_INFO "ISR CRIT TO PERI\n");
2004     		goto isr_done;
2005     	}
2006     
2007     	/* On a 508 Card, if critical due to if_send 
2008              * Major Error !!! */
2009     	if(card->hw.type != SDLA_S514) {
2010     		if(test_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
2011     			printk(KERN_INFO "%s: Critical while in ISR: %lx\n",
2012     				card->devname, card->wandev.critical);
2013     			card->in_isr = 0;
2014     			flags->interrupt_info_struct.interrupt_type = 0;
2015     			return;
2016     		}
2017     	}
2018     
2019     	switch(flags->interrupt_info_struct.interrupt_type) {
2020     
2021     	case RX_APP_INT_PEND:	/* 0x01: receive interrupt */
2022     		rx_intr(card);
2023     		break;
2024     
2025     	case TX_APP_INT_PEND:	/* 0x02: transmit interrupt */
2026     		flags->interrupt_info_struct.interrupt_permission &=
2027     			 ~APP_INT_ON_TX_FRAME;
2028     
2029     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2030     
2031     		if (card->tty_opt){
2032     			wanpipe_tty_trigger_poll(card);
2033     			break;
2034     		}
2035     
2036     		if (dev && is_queue_stopped(dev)){
2037     			if (card->u.c.usedby == API){
2038     				start_net_queue(dev);
2039     				wakeup_sk_bh(dev);
2040     			}else{
2041     				wake_net_dev(dev);
2042     			}
2043     		}
2044     #else
2045     		wake_net_dev(dev);
2046     #endif
2047     		break;
2048     
2049     	case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
2050     		++ Intr_test_counter;
2051     		break;
2052     
2053     	case CHDLC_EXCEP_COND_APP_INT_PEND:	/* 0x20 */
2054     		process_chdlc_exception(card);
2055     		break;
2056     
2057     	case GLOBAL_EXCEP_COND_APP_INT_PEND:
2058     		process_global_exception(card);
2059     		break;
2060     
2061     	case TIMER_APP_INT_PEND:
2062     		timer_intr(card);
2063     		break;
2064     
2065     	default:
2066     		printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n", 
2067     			card->devname,
2068     			flags->interrupt_info_struct.interrupt_type);
2069     		printk(KERN_INFO "Code name: ");
2070     		for(i = 0; i < 4; i ++)
2071     			printk(KERN_INFO "%c",
2072     				flags->global_info_struct.codename[i]); 
2073     		printk(KERN_INFO "\nCode version: ");
2074     	 	for(i = 0; i < 4; i ++)
2075     			printk(KERN_INFO "%c", 
2076     				flags->global_info_struct.codeversion[i]); 
2077     		printk(KERN_INFO "\n");	
2078     		break;
2079     	}
2080     
2081     isr_done:
2082     
2083     	card->in_isr = 0;
2084     	flags->interrupt_info_struct.interrupt_type = 0;
2085     	return;
2086     }
2087     
2088     /*============================================================================
2089      * Receive interrupt handler.
2090      */
2091     static void rx_intr (sdla_t* card)
2092     {
2093     	netdevice_t *dev;
2094     	chdlc_private_area_t *chdlc_priv_area;
2095     	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
2096     	CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
2097     	struct sk_buff *skb;
2098     	unsigned len;
2099     	unsigned addr = rxbuf->ptr_data_bfr;
2100     	void *buf;
2101     	int i,udp_type;
2102     
2103     	if (rxbuf->opp_flag != 0x01) {
2104     		printk(KERN_INFO 
2105     			"%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n", 
2106     			card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
2107                     printk(KERN_INFO "Code name: ");
2108                     for(i = 0; i < 4; i ++)
2109                             printk(KERN_INFO "%c",
2110                                     flags->global_info_struct.codename[i]);
2111                     printk(KERN_INFO "\nCode version: ");
2112                     for(i = 0; i < 4; i ++)
2113                             printk(KERN_INFO "%c",
2114                                     flags->global_info_struct.codeversion[i]);
2115                     printk(KERN_INFO "\n");
2116     
2117     
2118     		/* Bug Fix: Mar 6 2000
2119                      * If we get a corrupted mailbox, it measn that driver 
2120                      * is out of sync with the firmware. There is no recovery.
2121                      * If we don't turn off all interrupts for this card
2122                      * the machine will crash. 
2123                      */
2124     		printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
2125     		printk(KERN_INFO "Please contact Sangoma Technologies !\n");
2126     		chdlc_set_intr_mode(card,0);	
2127     		return;
2128     	}
2129     
2130     	len  = rxbuf->frame_length;
2131     
2132     #if defined(LINUX_2_4) || defined(LINUX_2_1)	
2133     	if (card->tty_opt){
2134     
2135     		if (rxbuf->error_flag){	
2136     			goto rx_exit;
2137     		}
2138     
2139     		if (len <= CRC_LENGTH){
2140     			goto rx_exit;
2141     		}
2142     		
2143     		if (!card->u.c.async_mode){
2144     			len -= CRC_LENGTH;
2145     		}
2146     
2147     		wanpipe_tty_receive(card,addr,len);
2148     		goto rx_exit;
2149     	}
2150     #endif
2151     
2152     	dev = card->wandev.dev;
2153     
2154     	if (!dev){
2155     		goto rx_exit;
2156     	}
2157     
2158     	if (!is_dev_running(dev))
2159     		goto rx_exit;
2160     
2161     	chdlc_priv_area = dev->priv;
2162     
2163     	
2164     	/* Allocate socket buffer */
2165     	skb = dev_alloc_skb(len);
2166     
2167     	if (skb == NULL) {
2168     		printk(KERN_INFO "%s: no socket buffers available!\n",
2169     					card->devname);
2170     		++card->wandev.stats.rx_dropped;
2171     		goto rx_exit;
2172     	}
2173     
2174     	/* Copy data to the socket buffer */
2175     	if((addr + len) > card->u.c.rx_top + 1) {
2176     		unsigned tmp = card->u.c.rx_top - addr + 1;
2177     		buf = skb_put(skb, tmp);
2178     		sdla_peek(&card->hw, addr, buf, tmp);
2179     		addr = card->u.c.rx_base;
2180     		len -= tmp;
2181     	}
2182     		
2183     	buf = skb_put(skb, len);
2184     	sdla_peek(&card->hw, addr, buf, len);
2185     
2186     	skb->protocol = htons(ETH_P_IP);
2187     
2188     	card->wandev.stats.rx_packets ++;
2189     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2190     	card->wandev.stats.rx_bytes += skb->len;
2191     #endif
2192     	udp_type = udp_pkt_type( skb, card );
2193     
2194     	if(udp_type == UDP_CPIPE_TYPE) {
2195     		if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
2196        				      card, skb, dev, chdlc_priv_area)) {
2197          		        flags->interrupt_info_struct.
2198     						interrupt_permission |= 
2199     							APP_INT_ON_TIMER; 
2200     		}
2201     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2202     	} else if(card->u.c.usedby == API) {
2203     
2204     		api_rx_hdr_t* api_rx_hdr;
2205            		skb_push(skb, sizeof(api_rx_hdr_t));
2206                     api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00];
2207     		api_rx_hdr->error_flag = rxbuf->error_flag;
2208          		api_rx_hdr->time_stamp = rxbuf->time_stamp;
2209     
2210                     skb->protocol = htons(PVC_PROT);
2211          		skb->mac.raw  = skb->data;
2212     		skb->dev      = dev;
2213                    	skb->pkt_type = WAN_PACKET_DATA;
2214     
2215     		bh_enqueue(dev, skb);
2216     
2217     		if (!test_and_set_bit(0,&chdlc_priv_area->tq_working)){
2218     			wanpipe_queue_tq(&chdlc_priv_area->common.wanpipe_task);
2219     		        wanpipe_mark_bh();
2220     		}
2221     #endif
2222     	}else{
2223     		/* FIXME: we should check to see if the received packet is a 
2224                               multicast packet so that we can increment the multicast 
2225                               statistic
2226                               ++ chdlc_priv_area->if_stats.multicast;
2227     		*/
2228                    	/* Pass it up the protocol stack */
2229     	
2230                     skb->dev = dev;
2231                     skb->mac.raw  = skb->data;
2232                     netif_rx(skb);
2233     	}
2234     
2235     rx_exit:
2236     	/* Release buffer element and calculate a pointer to the next one */
2237     	rxbuf->opp_flag = 0x00;
2238     	card->u.c.rxmb = ++ rxbuf;
2239     	if((void*)rxbuf > card->u.c.rxbuf_last){
2240     		card->u.c.rxmb = card->u.c.rxbuf_base;
2241     	}
2242     }
2243     
2244     /*============================================================================
2245      * Timer interrupt handler.
2246      * The timer interrupt is used for two purposes:
2247      *    1) Processing udp calls from 'cpipemon'.
2248      *    2) Reading board-level statistics for updating the proc file system.
2249      */
2250     void timer_intr(sdla_t *card)
2251     {
2252             netdevice_t* dev;
2253             chdlc_private_area_t* chdlc_priv_area = NULL;
2254             SHARED_MEMORY_INFO_STRUCT* flags = NULL;
2255     
2256             if ((dev = card->wandev.dev)==NULL){
2257     		flags = card->u.c.flags;
2258                     flags->interrupt_info_struct.interrupt_permission &=
2259                             ~APP_INT_ON_TIMER;
2260     		return;
2261     	}
2262     	
2263             chdlc_priv_area = dev->priv;
2264     
2265     	if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) {
2266     		if (!config_chdlc(card)){
2267     			chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
2268     		}
2269     	}
2270     
2271     	/* process a udp call if pending */
2272            	if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
2273                    	process_udp_mgmt_pkt(card, dev,
2274                            chdlc_priv_area);
2275     		chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
2276             }
2277     
2278     	/* read the communications statistics if required */
2279     	if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
2280     		update_comms_stats(card, chdlc_priv_area);
2281                     if(!(-- chdlc_priv_area->update_comms_stats)) {
2282     			chdlc_priv_area->timer_int_enabled &= 
2283     				~TMR_INT_ENABLED_UPDATE;
2284     		}
2285             }
2286     
2287     	/* only disable the timer interrupt if there are no udp or statistic */
2288     	/* updates pending */
2289             if(!chdlc_priv_area->timer_int_enabled) {
2290                     flags = card->u.c.flags;
2291                     flags->interrupt_info_struct.interrupt_permission &=
2292                             ~APP_INT_ON_TIMER;
2293             }
2294     }
2295     
2296     /*------------------------------------------------------------------------------
2297       Miscellaneous Functions
2298     	- set_chdlc_config() used to set configuration options on the board
2299     ------------------------------------------------------------------------------*/
2300     
2301     static int set_chdlc_config(sdla_t* card)
2302     {
2303     	CHDLC_CONFIGURATION_STRUCT cfg;
2304     
2305     	memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
2306     
2307     	if(card->wandev.clocking){
2308     		cfg.baud_rate = card->wandev.bps;
2309     	}
2310     		
2311     	cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
2312     		INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
2313     
2314     	cfg.modem_config_options	= 0;
2315     	cfg.modem_status_timer		= 100;
2316     
2317     	cfg.CHDLC_protocol_options	= card->u.c.protocol_options;
2318     
2319     	if (card->tty_opt){
2320     		cfg.CHDLC_API_options	= DISCARD_RX_ERROR_FRAMES;
2321     	}
2322     	
2323     	cfg.percent_data_buffer_for_Tx  = (card->u.c.receive_only) ? 0 : 50;
2324     	cfg.CHDLC_statistics_options	= (CHDLC_TX_DATA_BYTE_COUNT_STAT |
2325     		CHDLC_RX_DATA_BYTE_COUNT_STAT);
2326     	
2327     	if (card->tty_opt){
2328     		card->wandev.mtu = TTY_CHDLC_MAX_MTU;
2329     	}
2330     	cfg.max_CHDLC_data_field_length	= card->wandev.mtu;
2331     	cfg.transmit_keepalive_timer	= card->u.c.kpalv_tx;
2332     	cfg.receive_keepalive_timer	= card->u.c.kpalv_rx;
2333     	cfg.keepalive_error_tolerance	= card->u.c.kpalv_err;
2334     	cfg.SLARP_request_timer		= card->u.c.slarp_timer;
2335     
2336     	if (cfg.SLARP_request_timer) {
2337     		cfg.IP_address		= 0;
2338     		cfg.IP_netmask		= 0;
2339     		
2340     	}else if (card->wandev.dev){
2341     		netdevice_t * dev = card->wandev.dev;
2342     		chdlc_private_area_t *chdlc_priv_area = dev->priv;
2343     		
2344     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2345                     struct in_device *in_dev = dev->ip_ptr;
2346     
2347     		if(in_dev != NULL) {
2348     			struct in_ifaddr *ifa = in_dev->ifa_list;
2349     
2350     			if (ifa != NULL ) {
2351     				cfg.IP_address	= ntohl(ifa->ifa_local);
2352     				cfg.IP_netmask	= ntohl(ifa->ifa_mask); 
2353     				chdlc_priv_area->IP_address = ntohl(ifa->ifa_local);
2354     				chdlc_priv_area->IP_netmask = ntohl(ifa->ifa_mask); 
2355     			}
2356     		}
2357     #else
2358                     cfg.IP_address          = ntohl(dev->pa_addr);
2359                     cfg.IP_netmask          = ntohl(dev->pa_mask);
2360     		chdlc_priv_area->IP_address = ntohl(dev->pa_addr);
2361     		chdlc_priv_area->IP_netmask = ntohl(dev->pa_mask);
2362     #endif
2363     
2364     		/* FIXME: We must re-think this message in next release
2365     		if((cfg.IP_address & 0x000000FF) > 2) {
2366     			printk(KERN_WARNING "\n");
2367     	                printk(KERN_WARNING "  WARNING:%s configured with an\n",
2368     				card->devname);
2369     			printk(KERN_WARNING "  invalid local IP address.\n");
2370                             printk(KERN_WARNING "  Slarp pragmatics will fail.\n");
2371                             printk(KERN_WARNING "  IP address should be of the\n");
2372     			printk(KERN_WARNING "  format A.B.C.1 or A.B.C.2.\n");
2373     		}
2374     		*/		
2375     	}
2376     	
2377     	return chdlc_configure(card, &cfg);
2378     }
2379     
2380     
2381     /*-----------------------------------------------------------------------------
2382        set_asy_config() used to set asynchronous configuration options on the board
2383     ------------------------------------------------------------------------------*/
2384     
2385     static int set_asy_config(sdla_t* card)
2386     {
2387     
2388             ASY_CONFIGURATION_STRUCT cfg;
2389      	CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
2390     	int err;
2391     
2392     	memset(&cfg, 0, sizeof(ASY_CONFIGURATION_STRUCT));
2393     
2394     	if(card->wandev.clocking)
2395     		cfg.baud_rate = card->wandev.bps;
2396     
2397     	cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
2398     		INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
2399     
2400     	cfg.modem_config_options	= 0;
2401     	cfg.asy_API_options 		= card->u.c.api_options;
2402     	cfg.asy_protocol_options	= card->u.c.protocol_options;
2403     	cfg.Tx_bits_per_char		= card->u.c.tx_bits_per_char;
2404     	cfg.Rx_bits_per_char		= card->u.c.rx_bits_per_char;
2405     	cfg.stop_bits			= card->u.c.stop_bits;
2406     	cfg.parity			= card->u.c.parity;
2407     	cfg.break_timer			= card->u.c.break_timer;
2408     	cfg.asy_Rx_inter_char_timer	= card->u.c.inter_char_timer; 
2409     	cfg.asy_Rx_complete_length	= card->u.c.rx_complete_length; 
2410     	cfg.XON_char			= card->u.c.xon_char;
2411     	cfg.XOFF_char			= card->u.c.xoff_char;
2412     	cfg.asy_statistics_options	= (CHDLC_TX_DATA_BYTE_COUNT_STAT |
2413     		CHDLC_RX_DATA_BYTE_COUNT_STAT);
2414     
2415     	mailbox->buffer_length = sizeof(ASY_CONFIGURATION_STRUCT);
2416     	memcpy(mailbox->data, &cfg, mailbox->buffer_length);
2417     	mailbox->command = SET_ASY_CONFIGURATION;
2418     	err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
2419     	if (err != COMMAND_OK) 
2420     		chdlc_error (card, err, mailbox);
2421     	return err;
2422     }
2423     
2424     /*============================================================================
2425      * Enable asynchronous communications.
2426      */
2427     
2428     static int asy_comm_enable (sdla_t* card)
2429     {
2430     
2431     	int err;
2432     	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2433     
2434     	mb->buffer_length = 0;
2435     	mb->command = ENABLE_ASY_COMMUNICATIONS;
2436     	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2437     	if (err != COMMAND_OK && card->wandev.dev)
2438     		chdlc_error(card, err, mb);
2439     	
2440     	if (!err)
2441     		card->u.c.comm_enabled = 1;
2442     
2443     	return err;
2444     }
2445     
2446     /*============================================================================
2447      * Process global exception condition
2448      */
2449     static int process_global_exception(sdla_t *card)
2450     {
2451     	CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
2452     	int err;
2453     
2454     	mbox->buffer_length = 0;
2455     	mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
2456     	err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
2457     
2458     	if(err != CMD_TIMEOUT ){
2459     	
2460     		switch(mbox->return_code) {
2461              
2462     	      	case EXCEP_MODEM_STATUS_CHANGE:
2463     
2464     			printk(KERN_INFO "%s: Modem status change\n",
2465     				card->devname);
2466     
2467     			switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
2468     				case (DCD_HIGH):
2469     					printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname);
2470     					break;
2471     				case (CTS_HIGH):
2472                                             printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname); 
2473     					break;
2474                                     case ((DCD_HIGH | CTS_HIGH)):
2475                                             printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname);
2476                                             break;
2477     				default:
2478                                             printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname);
2479                                             break;
2480     			}
2481     			break;
2482     
2483                     case EXCEP_TRC_DISABLED:
2484                             printk(KERN_INFO "%s: Line trace disabled\n",
2485     				card->devname);
2486                             break;
2487     
2488     		case EXCEP_IRQ_TIMEOUT:
2489     			printk(KERN_INFO "%s: IRQ timeout occurred\n",
2490     				card->devname); 
2491     			break;
2492     
2493     		case 0x17:
2494     			if (card->tty_opt){
2495     				if (card->tty && card->tty_open){ 
2496     					printk(KERN_INFO 
2497     						"%s: Modem Hangup Exception: Hanging Up!\n",
2498     						card->devname);
2499     					tty_hangup(card->tty);
2500     				}
2501     				break;
2502     			}
2503     
2504     			/* If TTY is not used just drop throught */
2505     			
2506                     default:
2507                             printk(KERN_INFO "%s: Global exception %x\n",
2508     				card->devname, mbox->return_code);
2509                             break;
2510                     }
2511     	}
2512     	return 0;
2513     }
2514     
2515     
2516     /*============================================================================
2517      * Process chdlc exception condition
2518      */
2519     static int process_chdlc_exception(sdla_t *card)
2520     {
2521     	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2522     	int err;
2523     
2524     	mb->buffer_length = 0;
2525     	mb->command = READ_CHDLC_EXCEPTION_CONDITION;
2526     	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2527     	if(err != CMD_TIMEOUT) {
2528     	
2529     		switch (err) {
2530     
2531     		case EXCEP_LINK_ACTIVE:
2532     			port_set_state(card, WAN_CONNECTED);
2533     			trigger_chdlc_poll(card->wandev.dev);
2534     			break;
2535     
2536     		case EXCEP_LINK_INACTIVE_MODEM:
2537     			port_set_state(card, WAN_DISCONNECTED);
2538     			unconfigure_ip(card);
2539     			trigger_chdlc_poll(card->wandev.dev);
2540     			break;
2541     
2542     		case EXCEP_LINK_INACTIVE_KPALV:
2543     			port_set_state(card, WAN_DISCONNECTED);
2544     			printk(KERN_INFO "%s: Keepalive timer expired.\n",
2545     				 		card->devname);
2546     			unconfigure_ip(card);
2547     			trigger_chdlc_poll(card->wandev.dev);
2548     			break;
2549     
2550     		case EXCEP_IP_ADDRESS_DISCOVERED:
2551     			if (configure_ip(card)) 
2552     				return -1;
2553     			break;
2554     
2555     		case EXCEP_LOOPBACK_CONDITION:
2556     			printk(KERN_INFO "%s: Loopback Condition Detected.\n",
2557     						card->devname);
2558     			break;
2559     
2560     		case NO_CHDLC_EXCEP_COND_TO_REPORT:
2561     			printk(KERN_INFO "%s: No exceptions reported.\n",
2562     						card->devname);
2563     			break;
2564     		}
2565     
2566     	}
2567     	return 0;
2568     }
2569     
2570     
2571     /*============================================================================
2572      * Configure IP from SLARP negotiation
2573      * This adds dynamic routes when SLARP has provided valid addresses
2574      */
2575     
2576     static int configure_ip (sdla_t* card)
2577     {
2578     	netdevice_t *dev = card->wandev.dev;
2579             chdlc_private_area_t *chdlc_priv_area;
2580             char err;
2581     
2582     	if (!dev)
2583     		return 0;
2584     
2585     	chdlc_priv_area = dev->priv;
2586     	
2587     	
2588             /* set to discover */
2589             if(card->u.c.slarp_timer != 0x00) {
2590     		CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2591     		CHDLC_CONFIGURATION_STRUCT *cfg;
2592     
2593          		mb->buffer_length = 0;
2594     		mb->command = READ_CHDLC_CONFIGURATION;
2595     		err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2596     	
2597     		if(err != COMMAND_OK) {
2598     			chdlc_error(card,err,mb);
2599     			return -1;
2600     		}
2601     
2602     		cfg = (CHDLC_CONFIGURATION_STRUCT *)mb->data;
2603                     chdlc_priv_area->IP_address = cfg->IP_address;
2604                     chdlc_priv_area->IP_netmask = cfg->IP_netmask;
2605     
2606     		/* Set flag to add route */
2607     		chdlc_priv_area->route_status = ADD_ROUTE;
2608     
2609     		/* The idea here is to add the route in the poll routine.
2610     	   	This way, we aren't in interrupt context when adding routes */
2611     		trigger_chdlc_poll(dev);
2612             }
2613     
2614     	return 0;
2615     }
2616     
2617     
2618     /*============================================================================
2619      * Un-Configure IP negotiated by SLARP
2620      * This removes dynamic routes when the link becomes inactive.
2621      */
2622     
2623     static int unconfigure_ip (sdla_t* card)
2624     {
2625     	netdevice_t *dev = card->wandev.dev;
2626     	chdlc_private_area_t *chdlc_priv_area;
2627     
2628     	if (!dev)
2629     		return 0;
2630     
2631     	chdlc_priv_area= dev->priv;
2632     	
2633     	if (chdlc_priv_area->route_status == ROUTE_ADDED) {
2634     
2635     		/* Note: If this function is called, the 
2636                      * port state has been DISCONNECTED.  This state
2637                      * change will trigger a poll_disconnected 
2638                      * function, that will check for this condition. 
2639     		 */
2640     		chdlc_priv_area->route_status = REMOVE_ROUTE;
2641     
2642     	}
2643     	return 0;
2644     }
2645     
2646     /*============================================================================
2647      * Routine to add/remove routes 
2648      * Called like a polling routine when Routes are flagged to be added/removed.
2649      */
2650     
2651     static void process_route (sdla_t *card)
2652     {
2653             netdevice_t *dev = card->wandev.dev;
2654             unsigned char port_num;
2655             chdlc_private_area_t *chdlc_priv_area = NULL;
2656     	u32 local_IP_addr = 0;
2657     	u32 remote_IP_addr = 0;
2658     	u32 IP_netmask, IP_addr;
2659             int err = 0;
2660     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2661     	struct in_device *in_dev;
2662     	mm_segment_t fs;
2663     	struct ifreq if_info;
2664             struct sockaddr_in *if_data1, *if_data2;
2665     #else
2666     	unsigned long fs = 0;
2667             struct rtentry route;
2668     #endif
2669     	
2670             chdlc_priv_area = dev->priv;
2671             port_num = card->u.c.comm_port;
2672     
2673     	/* Bug Fix Mar 16 2000
2674     	 * AND the IP address to the Mask before checking
2675              * the last two bits. */
2676     
2677     	if((chdlc_priv_area->route_status == ADD_ROUTE) &&
2678     		((chdlc_priv_area->IP_address & ~chdlc_priv_area->IP_netmask) > 2)) {
2679     
2680     		printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname);
2681     
2682                     if(card->u.c.slarp_timer) {
2683     
2684     			printk(KERN_INFO "%s: Bad IP address %s received\n",
2685     				card->devname,
2686     				in_ntoa(ntohl(chdlc_priv_area->IP_address)));
2687                             printk(KERN_INFO "%s: from remote station.\n",
2688     				card->devname);
2689     
2690                     }else{ 
2691     
2692                             printk(KERN_INFO "%s: Bad IP address %s issued\n",
2693     				card->devname,
2694     				in_ntoa(ntohl(chdlc_priv_area->IP_address)));
2695                             printk(KERN_INFO "%s: to remote station. Local\n",
2696     				card->devname);
2697     			printk(KERN_INFO "%s: IP address must be A.B.C.1\n",
2698     				card->devname);
2699     			printk(KERN_INFO "%s: or A.B.C.2.\n",card->devname);
2700     		}
2701     
2702     		/* remove the route due to the IP address error condition */
2703     		chdlc_priv_area->route_status = REMOVE_ROUTE;
2704     		err = 1;
2705        	}
2706     
2707     	/* If we are removing a route with bad IP addressing, then use the */
2708     	/* locally configured IP addresses */
2709             if((chdlc_priv_area->route_status == REMOVE_ROUTE) && err) {
2710     
2711      	        /* do not remove a bad route that has already been removed */
2712             	if(chdlc_priv_area->route_removed) {
2713     	                return;
2714             	}
2715     
2716     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2717                     in_dev = dev->ip_ptr;
2718     
2719                     if(in_dev != NULL) {
2720                             struct in_ifaddr *ifa = in_dev->ifa_list;
2721                             if (ifa != NULL ) {
2722                                     local_IP_addr = ifa->ifa_local;
2723                                     IP_netmask  = ifa->ifa_mask;
2724                             }
2725                     }
2726     #else
2727                     local_IP_addr = dev->pa_addr;
2728                     remote_IP_addr = dev->pa_dstaddr;
2729                     IP_netmask = dev->pa_mask;
2730     #endif
2731     	}else{ 
2732            		/* According to Cisco HDLC, if the point-to-point address is
2733     		   A.B.C.1, then we are the opposite (A.B.C.2), and vice-versa.
2734     		*/
2735     		IP_netmask = ntohl(chdlc_priv_area->IP_netmask);
2736     	        remote_IP_addr = ntohl(chdlc_priv_area->IP_address);
2737     	
2738     
2739     		/* If Netmask is 255.255.255.255 the local address
2740                      * calculation will fail. Default it back to 255.255.255.0 */
2741     		if (IP_netmask == 0xffffffff)
2742     			IP_netmask &= 0x00ffffff;
2743     
2744     		/* Bug Fix Mar 16 2000
2745     		 * AND the Remote IP address with IP netmask, instead
2746                      * of static netmask of 255.255.255.0 */
2747             	local_IP_addr = (remote_IP_addr & IP_netmask) +
2748                     	(~remote_IP_addr & ntohl(0x0003));
2749     
2750     	        if(!card->u.c.slarp_timer) {
2751     			IP_addr = local_IP_addr;
2752     			local_IP_addr = remote_IP_addr;
2753     			remote_IP_addr = IP_addr;
2754            		}
2755     	}
2756     
2757             fs = get_fs();                  /* Save file system  */
2758             set_fs(get_ds());               /* Get user space block */
2759     
2760     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2761             /* Setup a structure for adding/removing routes */
2762             memset(&if_info, 0, sizeof(if_info));
2763             strcpy(if_info.ifr_name, dev->name);
2764     
2765     #else
2766     	/* Setup a structure for adding/removing routes */
2767     	dev->pa_mask = IP_netmask;
2768     	dev->pa_dstaddr = remote_IP_addr;
2769     	dev->pa_addr = local_IP_addr;
2770     
2771     	memset(&route, 0, sizeof(route));
2772     	route.rt_dev = dev->name;
2773     	route.rt_flags = 0;
2774     	((struct sockaddr_in *)&(route.rt_dst))->sin_addr.s_addr =
2775     			dev->pa_dstaddr;
2776     	((struct sockaddr_in *)&(route.rt_dst))->sin_family = AF_INET;
2777     	((struct sockaddr_in *)&(route.rt_genmask))->sin_addr.s_addr =
2778     			0xFFFFFFFF;
2779             ((struct sockaddr_in *)&(route.rt_genmask))->sin_family =
2780     			AF_INET;
2781     #endif
2782     
2783     	switch (chdlc_priv_area->route_status) {
2784     
2785     	case ADD_ROUTE:
2786     
2787     		if(!card->u.c.slarp_timer) {
2788     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2789     			if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2790     			if_data2->sin_addr.s_addr = remote_IP_addr;
2791     			if_data2->sin_family = AF_INET;
2792     			err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2793     #else
2794                             err = ip_rt_new(&route);
2795     #endif
2796     		} else { 
2797     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2798     			if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
2799     			if_data1->sin_addr.s_addr = local_IP_addr;
2800     			if_data1->sin_family = AF_INET;
2801     			if(!(err = devinet_ioctl(SIOCSIFADDR, &if_info))){
2802     				if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2803     				if_data2->sin_addr.s_addr = remote_IP_addr;
2804     				if_data2->sin_family = AF_INET;
2805     				err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2806     			}
2807     #else
2808                    		err = ip_rt_new(&route);
2809     #endif
2810     		}
2811     
2812                    if(err) {
2813     			printk(KERN_INFO "%s: Add route %s failed (%d)\n", 
2814     				card->devname, in_ntoa(remote_IP_addr), err);
2815     		} else {
2816     			((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED;
2817     			printk(KERN_INFO "%s: Dynamic route added.\n",
2818     				card->devname);
2819     			printk(KERN_INFO "%s:    Local IP addr : %s\n",
2820     				card->devname, in_ntoa(local_IP_addr));
2821     			printk(KERN_INFO "%s:    Remote IP addr: %s\n",
2822     				card->devname, in_ntoa(remote_IP_addr));
2823     			chdlc_priv_area->route_removed = 0;
2824     		}
2825     		break;
2826     
2827     
2828     	case REMOVE_ROUTE:
2829     	
2830     #if defined(LINUX_2_1) || defined(LINUX_2_4)
2831     		/* Change the local ip address of the interface to 0.
2832     		 * This will also delete the destination route.
2833     		 */
2834     		if(!card->u.c.slarp_timer) {
2835     			if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2836     			if_data2->sin_addr.s_addr = 0;
2837     			if_data2->sin_family = AF_INET;
2838     			err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2839     		} else {
2840     			if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
2841     			if_data1->sin_addr.s_addr = 0;
2842     			if_data1->sin_family = AF_INET;
2843     			err = devinet_ioctl(SIOCSIFADDR,&if_info);
2844     		
2845     		}
2846     #else
2847     		/* set the point-to-point IP address to 0.0.0.0 */
2848     		dev->pa_dstaddr = 0; 
2849     		err = ip_rt_kill(&route);
2850     #endif
2851     		if(err) {
2852     			printk(KERN_INFO
2853     				"%s: Remove route %s failed, (err %d)\n",
2854     					card->devname, in_ntoa(remote_IP_addr),
2855     					err);
2856     		} else {
2857     			((chdlc_private_area_t *)dev->priv)->route_status =
2858     				NO_ROUTE;
2859                             printk(KERN_INFO "%s: Dynamic route removed: %s\n",
2860                                             card->devname, in_ntoa(local_IP_addr)); 
2861     			chdlc_priv_area->route_removed = 1;
2862     		}
2863     		break;
2864     	}
2865     
2866             set_fs(fs);                     /* Restore file system */
2867     
2868     }
2869     
2870     
2871     /*=============================================================================
2872      * Store a UDP management packet for later processing.
2873      */
2874     
2875     static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
2876                                     struct sk_buff *skb, netdevice_t* dev,
2877                                     chdlc_private_area_t* chdlc_priv_area )
2878     {
2879     	int udp_pkt_stored = 0;
2880     
2881     	if(!chdlc_priv_area->udp_pkt_lgth &&
2882     	  (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
2883             	chdlc_priv_area->udp_pkt_lgth = skb->len;
2884     		chdlc_priv_area->udp_pkt_src = udp_pkt_src;
2885            		memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
2886     		chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
2887     		udp_pkt_stored = 1;
2888     	}
2889     
2890     	if(udp_pkt_src == UDP_PKT_FRM_STACK){
2891     		wan_dev_kfree_skb(skb, FREE_WRITE);
2892     	}else{
2893                     wan_dev_kfree_skb(skb, FREE_READ);
2894     	}
2895     		
2896     	return(udp_pkt_stored);
2897     }
2898     
2899     
2900     /*=============================================================================
2901      * Process UDP management packet.
2902      */
2903     
2904     static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev,
2905     				chdlc_private_area_t* chdlc_priv_area ) 
2906     {
2907     	unsigned char *buf;
2908     	unsigned int frames, len;
2909     	struct sk_buff *new_skb;
2910     	unsigned short buffer_length, real_len;
2911     	unsigned long data_ptr;
2912     	unsigned data_length;
2913     	int udp_mgmt_req_valid = 1;
2914     	CHDLC_MAILBOX_STRUCT *mb = card->mbox;
2915     	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
2916     	chdlc_udp_pkt_t *chdlc_udp_pkt;
2917     	struct timeval tv;
2918     	int err;
2919     	char ut_char;
2920     
2921     	chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
2922     
2923     	if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
2924     
2925     		/* Only these commands are support for remote debugging.
2926     		 * All others are not */
2927     		switch(chdlc_udp_pkt->cblock.command) {
2928     
2929     			case READ_GLOBAL_STATISTICS:
2930     			case READ_MODEM_STATUS:  
2931     			case READ_CHDLC_LINK_STATUS:
2932     			case CPIPE_ROUTER_UP_TIME:
2933     			case READ_COMMS_ERROR_STATS:
2934     			case READ_CHDLC_OPERATIONAL_STATS:
2935     
2936     			/* These two commands are executed for
2937     			 * each request */
2938     			case READ_CHDLC_CONFIGURATION:
2939     			case READ_CHDLC_CODE_VERSION:
2940     				udp_mgmt_req_valid = 1;
2941     				break;
2942     			default:
2943     				udp_mgmt_req_valid = 0;
2944     				break;
2945     		} 
2946     	}
2947     	
2948       	if(!udp_mgmt_req_valid) {
2949     
2950     		/* set length to 0 */
2951     		chdlc_udp_pkt->cblock.buffer_length = 0;
2952     
2953         		/* set return code */
2954     		chdlc_udp_pkt->cblock.return_code = 0xCD;
2955     
2956     		if (net_ratelimit()){	
2957     			printk(KERN_INFO 
2958     			"%s: Warning, Illegal UDP command attempted from network: %x\n",
2959     			card->devname,chdlc_udp_pkt->cblock.command);
2960     		}
2961     
2962        	} else {
2963     	   	unsigned long trace_status_cfg_addr = 0;
2964     		TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
2965     		TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
2966     
2967     		switch(chdlc_udp_pkt->cblock.command) {
2968     
2969     		case CPIPE_ENABLE_TRACING:
2970     		     if (!chdlc_priv_area->TracingEnabled) {
2971     
2972     			/* OPERATE_DATALINE_MONITOR */
2973     
2974     			mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
2975     			mb->command = SET_TRACE_CONFIGURATION;
2976     
2977         			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
2978     				trace_config = TRACE_ACTIVE;
2979     			/* Trace delay mode is not used because it slows
2980     			   down transfer and results in a standoff situation
2981     			   when there is a lot of data */
2982     
2983     			/* Configure the Trace based on user inputs */
2984     			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |= 
2985     					chdlc_udp_pkt->data[0];
2986     
2987     			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
2988     			   trace_deactivation_timer = 4000;
2989     
2990     
2991     			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2992     			if (err != COMMAND_OK) {
2993     				chdlc_error(card,err,mb);
2994     				card->TracingEnabled = 0;
2995     				chdlc_udp_pkt->cblock.return_code = err;
2996     				mb->buffer_length = 0;
2997     				break;
2998     	    		} 
2999     
3000     			/* Get the base address of the trace element list */
3001     			mb->buffer_length = 0;
3002     			mb->command = READ_TRACE_CONFIGURATION;
3003     			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
3004     
3005     			if (err != COMMAND_OK) {
3006     				chdlc_error(card,err,mb);
3007     				chdlc_priv_area->TracingEnabled = 0;
3008     				chdlc_udp_pkt->cblock.return_code = err;
3009     				mb->buffer_length = 0;
3010     				break;
3011     	    		} 	
3012     
3013     	   		trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
3014     				mb->data) -> ptr_trace_stat_el_cfg_struct;
3015     
3016     			sdla_peek(&card->hw, trace_status_cfg_addr,
3017     				 &trace_cfg_struct, sizeof(trace_cfg_struct));
3018     		    
3019     			chdlc_priv_area->start_trace_addr = trace_cfg_struct.
3020     				base_addr_trace_status_elements;
3021     
3022     			chdlc_priv_area->number_trace_elements = 
3023     					trace_cfg_struct.number_trace_status_elements;
3024     
3025     			chdlc_priv_area->end_trace_addr = (unsigned long)
3026     					((TRACE_STATUS_ELEMENT_STRUCT *)
3027     					 chdlc_priv_area->start_trace_addr + 
3028     					 (chdlc_priv_area->number_trace_elements - 1));
3029     
3030     			chdlc_priv_area->base_addr_trace_buffer = 
3031     					trace_cfg_struct.base_addr_trace_buffer;
3032     
3033     			chdlc_priv_area->end_addr_trace_buffer = 
3034     					trace_cfg_struct.end_addr_trace_buffer;
3035     
3036     		    	chdlc_priv_area->curr_trace_addr = 
3037     					trace_cfg_struct.next_trace_element_to_use;
3038     
3039     	    		chdlc_priv_area->available_buffer_space = 2000 - 
3040     								  sizeof(ip_pkt_t) -
3041     								  sizeof(udp_pkt_t) -
3042     							      	  sizeof(wp_mgmt_t) -
3043     								  sizeof(cblock_t) -
3044     							          sizeof(trace_info_t);	
3045     	       	     }
3046     		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
3047     		     mb->buffer_length = 0;
3048     	       	     chdlc_priv_area->TracingEnabled = 1;
3049     	       	     break;
3050     	   
3051     
3052     		case CPIPE_DISABLE_TRACING:
3053     		     if (chdlc_priv_area->TracingEnabled) {
3054     
3055     			/* OPERATE_DATALINE_MONITOR */
3056     			mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
3057     			mb->command = SET_TRACE_CONFIGURATION;
3058         			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
3059     				trace_config = TRACE_INACTIVE;
3060     			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
3061     		     }		
3062     
3063     		     chdlc_priv_area->TracingEnabled = 0;
3064     		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
3065     		     mb->buffer_length = 0;
3066     		     break;
3067     	   
3068     
3069     		case CPIPE_GET_TRACE_INFO:
3070     
3071     		     if (!chdlc_priv_area->TracingEnabled) {
3072     			chdlc_udp_pkt->cblock.return_code = 1;
3073     			mb->buffer_length = 0;
3074     			break;
3075     		     }
3076     
3077       		     chdlc_udp_pkt->trace_info.ismoredata = 0x00;
3078     		     buffer_length = 0;	/* offset of packet already occupied */
3079     
3080     		     for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
3081     
3082     			trace_pkt_t *trace_pkt = (trace_pkt_t *)
3083     				&chdlc_udp_pkt->data[buffer_length];
3084     
3085     			sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
3086     			   	  (unsigned char *)&trace_element_struct,
3087     			   	  sizeof(TRACE_STATUS_ELEMENT_STRUCT));
3088     
3089          			if (trace_element_struct.opp_flag == 0x00) {
3090     			 	break;
3091     			}
3092     
3093     			/* get pointer to real data */
3094     			data_ptr = trace_element_struct.ptr_data_bfr;
3095     
3096     			/* See if there is actual data on the trace buffer */
3097     			if (data_ptr){
3098     				data_length = trace_element_struct.trace_length;
3099     			}else{
3100     				data_length = 0;
3101     				chdlc_udp_pkt->trace_info.ismoredata = 0x01;
3102     			}
3103     	
3104        			if( (chdlc_priv_area->available_buffer_space - buffer_length)
3105     				< ( sizeof(trace_pkt_t) + data_length) ) {
3106     
3107                                 /* indicate there are more frames on board & exit */
3108     				chdlc_udp_pkt->trace_info.ismoredata = 0x01;
3109                                    	break;
3110                              }
3111     
3112     			trace_pkt->status = trace_element_struct.trace_type;
3113     
3114     			trace_pkt->time_stamp =
3115