1/*****************************************************************************
2* wanpipe_multppp.c Multi-Port PPP driver module.
3*
4* Authors: 	Nenad Corbic <ncorbic@sangoma.com>
5*
6* Copyright:	(c) 1995-2001 Sangoma Technologies Inc.
7*
8*		This program is free software; you can redistribute it and/or
9*		modify it under the terms of the GNU General Public License
10*		as published by the Free Software Foundation; either version
11*		2 of the License, or (at your option) any later version.
12* ============================================================================
13* Dec 15 2000   Updated for 2.4.X kernel
14* Nov 15 2000   Fixed the SyncPPP support for kernels 2.2.16 and higher.
15*   		The pppstruct has changed.
16* Jul 13 2000	Using the kernel Syncppp module on top of RAW Wanpipe CHDLC
17*  		module.
18*****************************************************************************/
19
20#include <linux/module.h>
21#include <linux/version.h>
22#include <linux/kernel.h>	/* printk(), and other useful stuff */
23#include <linux/stddef.h>	/* offsetof(), etc. */
24#include <linux/errno.h>	/* return codes */
25#include <linux/string.h>	/* inline memset(), etc. */
26#include <linux/slab.h>	/* kmalloc(), kfree() */
27#include <linux/wanrouter.h>	/* WAN router definitions */
28#include <linux/wanpipe.h>	/* WANPIPE common user API definitions */
29#include <linux/if_arp.h>	/* ARPHRD_* defines */
30
31#include <linux/in.h>		/* sockaddr_in */
32#include <linux/inet.h>
33#include <linux/if.h>
34#include <asm/byteorder.h>	/* htons(), etc. */
35#include <linux/sdlapci.h>
36#include <asm/io.h>
37
38#include <linux/sdla_chdlc.h>		/* CHDLC firmware API definitions */
39#include <linux/sdla_asy.h>           	/* CHDLC (async) API definitions */
40
41#include <linux/if_wanpipe_common.h>    /* Socket Driver common area */
42#include <linux/if_wanpipe.h>
43
44
45#if defined(LINUX_2_1) || defined(LINUX_2_4)
46  #include <linux/inetdevice.h>
47  #include <asm/uaccess.h>
48
49#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,3)
50 #include <net/syncppp.h>
51#else
52 #include "syncppp.h"
53#endif
54
55#else
56  #include <net/route.h>          /* Adding new route entries */
57#endif
58
59/****** Defines & Macros ****************************************************/
60
61#ifdef	_DEBUG_
62#define	STATIC
63#else
64#define	STATIC		static
65#endif
66
67/* reasons for enabling the timer interrupt on the adapter */
68#define TMR_INT_ENABLED_UDP   	0x01
69#define TMR_INT_ENABLED_UPDATE	0x02
70#define TMR_INT_ENABLED_CONFIG  0x04
71
72#define	CHDLC_DFLT_DATA_LEN	1500		/* default MTU */
73#define CHDLC_HDR_LEN		1
74
75#define IFF_POINTTOPOINT 0x10
76
77#define CHDLC_API 0x01
78
79#define PORT(x)   (x == 0 ? "PRIMARY" : "SECONDARY" )
80#define MAX_BH_BUFF	10
81
82#define CRC_LENGTH 	2
83#define PPP_HEADER_LEN 	4
84
85/******Data Structures*****************************************************/
86
87/* This structure is placed in the private data area of the device structure.
88 * The card structure used to occupy the private area but now the following
89 * structure will incorporate the card structure along with CHDLC specific data
90 */
91
92typedef struct chdlc_private_area
93{
94	void *if_ptr;				/* General Pointer used by SPPP */
95	wanpipe_common_t common;
96	sdla_t		*card;
97	int 		TracingEnabled;		/* For enabling Tracing */
98	unsigned long 	curr_trace_addr;	/* Used for Tracing */
99	unsigned long 	start_trace_addr;
100	unsigned long 	end_trace_addr;
101	unsigned long 	base_addr_trace_buffer;
102	unsigned long 	end_addr_trace_buffer;
103	unsigned short 	number_trace_elements;
104	unsigned  	available_buffer_space;
105	unsigned long 	router_start_time;
106	unsigned char 	route_status;
107	unsigned char 	route_removed;
108	unsigned long 	tick_counter;		/* For 5s timeout counter */
109	unsigned long 	router_up_time;
110        u32             IP_address;		/* IP addressing */
111        u32             IP_netmask;
112	unsigned char  mc;			/* Mulitcast support on/off */
113	unsigned short udp_pkt_lgth;		/* udp packet processing */
114	char udp_pkt_src;
115	char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
116	unsigned short timer_int_enabled;
117	char update_comms_stats;		/* updating comms stats */
118
119	//FIXME: add driver stats as per frame relay!
120
121} chdlc_private_area_t;
122
123/* Route Status options */
124#define NO_ROUTE	0x00
125#define ADD_ROUTE	0x01
126#define ROUTE_ADDED	0x02
127#define REMOVE_ROUTE	0x03
128
129
130/* variable for keeping track of enabling/disabling FT1 monitor status */
131static int rCount = 0;
132
133/* variable for tracking how many interfaces to open for WANPIPE on the
134   two ports */
135
136extern void disable_irq(unsigned int);
137extern void enable_irq(unsigned int);
138
139/****** Function Prototypes *************************************************/
140/* WAN link driver entry points. These are called by the WAN router module. */
141static int update (wan_device_t* wandev);
142static int new_if (wan_device_t* wandev, netdevice_t* dev,
143	wanif_conf_t* conf);
144static int del_if (wan_device_t* wandev, netdevice_t* dev);
145
146/* Network device interface */
147static int if_init   (netdevice_t* dev);
148static int if_open   (netdevice_t* dev);
149static int if_close  (netdevice_t* dev);
150static int if_send (struct sk_buff* skb, netdevice_t* dev);
151#if defined(LINUX_2_1) || defined(LINUX_2_4)
152static struct net_device_stats* if_stats (netdevice_t* dev);
153#else
154static struct enet_statistics* if_stats (netdevice_t* dev);
155#endif
156
157#ifdef LINUX_2_4
158static void if_tx_timeout (netdevice_t *dev);
159#endif
160
161/* CHDLC Firmware interface functions */
162static int chdlc_configure 	(sdla_t* card, void* data);
163static int chdlc_comm_enable 	(sdla_t* card);
164static int chdlc_comm_disable 	(sdla_t* card);
165static int chdlc_read_version 	(sdla_t* card, char* str);
166static int chdlc_set_intr_mode 	(sdla_t* card, unsigned mode);
167static int chdlc_send (sdla_t* card, void* data, unsigned len);
168static int chdlc_read_comm_err_stats (sdla_t* card);
169static int chdlc_read_op_stats (sdla_t* card);
170static int config_chdlc (sdla_t *card);
171
172
173/* Miscellaneous CHDLC Functions */
174static int set_chdlc_config (sdla_t* card);
175static void init_chdlc_tx_rx_buff( sdla_t* card, netdevice_t *dev );
176static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
177static int process_chdlc_exception(sdla_t *card);
178static int process_global_exception(sdla_t *card);
179static int update_comms_stats(sdla_t* card,
180        chdlc_private_area_t* chdlc_priv_area);
181static void port_set_state (sdla_t *card, int);
182
183/* Interrupt handlers */
184static void wsppp_isr (sdla_t* card);
185static void rx_intr (sdla_t* card);
186static void timer_intr(sdla_t *);
187
188/* Miscellaneous functions */
189static int reply_udp( unsigned char *data, unsigned int mbox_len );
190static int intr_test( sdla_t* card);
191static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
192static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
193                                struct sk_buff *skb, netdevice_t* dev,
194                                chdlc_private_area_t* chdlc_priv_area);
195static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev,
196				chdlc_private_area_t* chdlc_priv_area);
197static unsigned short calc_checksum (char *, int);
198static void s508_lock (sdla_t *card, unsigned long *smp_flags);
199static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
200static void send_ppp_term_request (netdevice_t*);
201
202
203static int  Intr_test_counter;
204/****** Public Functions ****************************************************/
205
206/*============================================================================
207 * Cisco HDLC protocol initialization routine.
208 *
209 * This routine is called by the main WANPIPE module during setup.  At this
210 * point adapter is completely initialized and firmware is running.
211 *  o read firmware version (to make sure it's alive)
212 *  o configure adapter
213 *  o initialize protocol-specific fields of the adapter data space.
214 *
215 * Return:	0	o.k.
216 *		< 0	failure.
217 */
218int wsppp_init (sdla_t* card, wandev_conf_t* conf)
219{
220	unsigned char port_num;
221	int err;
222	unsigned long max_permitted_baud = 0;
223	SHARED_MEMORY_INFO_STRUCT *flags;
224
225	union
226		{
227		char str[80];
228		} u;
229	volatile CHDLC_MAILBOX_STRUCT* mb;
230	CHDLC_MAILBOX_STRUCT* mb1;
231	unsigned long timeout;
232
233	/* Verify configuration ID */
234	if (conf->config_id != WANCONFIG_MPPP) {
235		printk(KERN_INFO "%s: invalid configuration ID %u!\n",
236				  card->devname, conf->config_id);
237		return -EINVAL;
238	}
239
240	/* Find out which Port to use */
241	if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
242		if (card->next){
243
244			if (conf->comm_port != card->next->u.c.comm_port){
245				card->u.c.comm_port = conf->comm_port;
246			}else{
247				printk(KERN_ERR "%s: ERROR - %s port used!\n",
248        		        	card->wandev.name, PORT(conf->comm_port));
249				return -EINVAL;
250			}
251		}else{
252			card->u.c.comm_port = conf->comm_port;
253		}
254	}else{
255		printk(KERN_ERR "%s: ERROR - Invalid Port Selected!\n",
256                			card->wandev.name);
257		return -EINVAL;
258	}
259
260
261	/* Initialize protocol-specific fields */
262	if(card->hw.type != SDLA_S514){
263
264		if (card->u.c.comm_port == WANOPT_PRI){
265			card->mbox  = (void *) card->hw.dpmbase;
266		}else{
267			card->mbox  = (void *) card->hw.dpmbase +
268				SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
269		}
270	}else{
271		/* for a S514 adapter, set a pointer to the actual mailbox in the */
272		/* allocated virtual memory area */
273		if (card->u.c.comm_port == WANOPT_PRI){
274			card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
275		}else{
276			card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
277		}
278	}
279
280	mb = mb1 = card->mbox;
281
282	if (!card->configured){
283
284		/* The board will place an 'I' in the return code to indicate that it is
285	   	ready to accept commands.  We expect this to be completed in less
286           	than 1 second. */
287
288		timeout = jiffies;
289		while (mb->return_code != 'I')	/* Wait 1s for board to initialize */
290			if ((jiffies - timeout) > 1*HZ) break;
291
292		if (mb->return_code != 'I') {
293			printk(KERN_INFO
294				"%s: Initialization not completed by adapter\n",
295				card->devname);
296			printk(KERN_INFO "Please contact Sangoma representative.\n");
297			return -EIO;
298		}
299	}
300
301	/* Read firmware version.  Note that when adapter initializes, it
302	 * clears the mailbox, so it may appear that the first command was
303	 * executed successfully when in fact it was merely erased. To work
304	 * around this, we execute the first command twice.
305	 */
306
307	if (chdlc_read_version(card, u.str))
308		return -EIO;
309
310	printk(KERN_INFO "%s: Running Raw CHDLC firmware v%s\n"
311			 "%s: for Multi-Port PPP protocol.\n",
312			card->devname,u.str,card->devname);
313
314	card->isr			= &wsppp_isr;
315	card->poll			= NULL;
316	card->exec			= NULL;
317	card->wandev.update		= &update;
318 	card->wandev.new_if		= &new_if;
319	card->wandev.del_if		= &del_if;
320	card->wandev.udp_port   	= conf->udp_port;
321
322	card->wandev.new_if_cnt = 0;
323
324	/* reset the number of times the 'update()' proc has been called */
325	card->u.c.update_call_count = 0;
326
327	card->wandev.ttl = conf->ttl;
328	card->wandev.interface = conf->interface;
329
330	if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
331	    card->hw.type != SDLA_S514){
332		printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n",
333			card->devname, PORT(card->u.c.comm_port));
334		return -EIO;
335	}
336
337
338	card->wandev.clocking = conf->clocking;
339
340	port_num = card->u.c.comm_port;
341
342	/* Setup Port Bps */
343
344	if(card->wandev.clocking) {
345		if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
346			/* For Primary Port 0 */
347               		max_permitted_baud =
348				(card->hw.type == SDLA_S514) ?
349				PRI_MAX_BAUD_RATE_S514 :
350				PRI_MAX_BAUD_RATE_S508;
351		}
352		else if(port_num == WANOPT_SEC) {
353			/* For Secondary Port 1 */
354                        max_permitted_baud =
355                               (card->hw.type == SDLA_S514) ?
356                                SEC_MAX_BAUD_RATE_S514 :
357                                SEC_MAX_BAUD_RATE_S508;
358                        }
359
360			if(conf->bps > max_permitted_baud) {
361				conf->bps = max_permitted_baud;
362				printk(KERN_INFO "%s: Baud too high!\n",
363					card->wandev.name);
364 				printk(KERN_INFO "%s: Baud rate set to %lu bps\n",
365					card->wandev.name, max_permitted_baud);
366			}
367
368			card->wandev.bps = conf->bps;
369	}else{
370        	card->wandev.bps = 0;
371  	}
372
373	/* Setup the Port MTU */
374	if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
375
376		/* For Primary Port 0 */
377		card->wandev.mtu =
378			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
379			min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
380			CHDLC_DFLT_DATA_LEN;
381	} else if(port_num == WANOPT_SEC) {
382		/* For Secondary Port 1 */
383		card->wandev.mtu =
384			(conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
385			min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
386			CHDLC_DFLT_DATA_LEN;
387	}
388
389	/* Add on a PPP Header */
390	card->wandev.mtu += PPP_HEADER_LEN;
391
392	/* Set up the interrupt status area */
393	/* Read the CHDLC Configuration and obtain:
394	 *	Ptr to shared memory infor struct
395         * Use this pointer to calculate the value of card->u.c.flags !
396 	 */
397	mb1->buffer_length = 0;
398	mb1->command = READ_CHDLC_CONFIGURATION;
399	err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
400	if(err != COMMAND_OK) {
401		clear_bit(1, (void*)&card->wandev.critical);
402
403                if(card->hw.type != SDLA_S514)
404                	enable_irq(card->hw.irq);
405
406		chdlc_error(card, err, mb1);
407		return -EIO;
408	}
409
410	if(card->hw.type == SDLA_S514){
411               	card->u.c.flags = (void *)(card->hw.dpmbase +
412               		(((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
413			ptr_shared_mem_info_struct));
414        }else{
415                card->u.c.flags = (void *)(card->hw.dpmbase +
416                        (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
417			ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
418	}
419
420	flags = card->u.c.flags;
421
422	/* This is for the ports link state */
423	card->wandev.state = WAN_DUALPORT;
424	card->u.c.state = WAN_DISCONNECTED;
425
426
427	if (!card->wandev.piggyback){
428		err = intr_test(card);
429
430		if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
431			printk(KERN_ERR "%s: Interrupt test failed (%i)\n",
432					card->devname, Intr_test_counter);
433			printk(KERN_ERR "%s: Please choose another interrupt\n",
434					card->devname);
435			return  -EIO;
436		}
437
438		printk(KERN_INFO "%s: Interrupt test passed (%i)\n",
439				card->devname, Intr_test_counter);
440	}
441
442
443	if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
444		printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
445				card->devname);
446		return -EIO;
447        }
448
449	/* Mask the Timer interrupt */
450	flags->interrupt_info_struct.interrupt_permission &=
451		~APP_INT_ON_TIMER;
452
453	printk(KERN_INFO "\n");
454
455	return 0;
456}
457
458/******* WAN Device Driver Entry Points *************************************/
459
460/*============================================================================
461 * Update device status & statistics
462 * This procedure is called when updating the PROC file system and returns
463 * various communications statistics. These statistics are accumulated from 3
464 * different locations:
465 * 	1) The 'if_stats' recorded for the device.
466 * 	2) Communication error statistics on the adapter.
467 *      3) CHDLC operational statistics on the adapter.
468 * The board level statistics are read during a timer interrupt. Note that we
469 * read the error and operational statistics during consecitive timer ticks so
470 * as to minimize the time that we are inside the interrupt handler.
471 *
472 */
473static int update (wan_device_t* wandev)
474{
475	sdla_t* card = wandev->private;
476 	netdevice_t* dev;
477        volatile chdlc_private_area_t* chdlc_priv_area;
478        SHARED_MEMORY_INFO_STRUCT *flags;
479	unsigned long timeout;
480
481	/* sanity checks */
482	if((wandev == NULL) || (wandev->private == NULL))
483		return -EFAULT;
484
485	if(wandev->state == WAN_UNCONFIGURED)
486		return -ENODEV;
487
488	/* more sanity checks */
489        if(!card->u.c.flags)
490                return -ENODEV;
491
492	if((dev=card->wandev.dev) == NULL)
493		return -ENODEV;
494
495	if((chdlc_priv_area=dev->priv) == NULL)
496		return -ENODEV;
497
498      	flags = card->u.c.flags;
499
500       	if(chdlc_priv_area->update_comms_stats){
501		return -EAGAIN;
502	}
503
504	/* we will need 2 timer interrupts to complete the */
505	/* reading of the statistics */
506	chdlc_priv_area->update_comms_stats = 2;
507       	flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
508	chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
509
510	/* wait a maximum of 1 second for the statistics to be updated */
511        timeout = jiffies;
512        for(;;) {
513		if(chdlc_priv_area->update_comms_stats == 0)
514			break;
515                if ((jiffies - timeout) > (1 * HZ)){
516    			chdlc_priv_area->update_comms_stats = 0;
517 			chdlc_priv_area->timer_int_enabled &=
518				~TMR_INT_ENABLED_UPDATE;
519 			return -EAGAIN;
520		}
521        }
522
523	return 0;
524}
525
526
527/*============================================================================
528 * Create new logical channel.
529 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
530 * handled.
531 * o parse media- and hardware-specific configuration
532 * o make sure that a new channel can be created
533 * o allocate resources, if necessary
534 * o prepare network device structure for registaration.
535 *
536 * Return:	0	o.k.
537 *		< 0	failure (channel will not be created)
538 */
539static int new_if (wan_device_t* wandev, netdevice_t* pdev, wanif_conf_t* conf)
540{
541
542	struct ppp_device *pppdev = (struct ppp_device *)pdev;
543	netdevice_t *dev=NULL;
544	struct sppp *sp;
545	sdla_t* card = wandev->private;
546	chdlc_private_area_t* chdlc_priv_area;
547
548	if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
549		printk(KERN_INFO "%s: invalid interface name!\n",
550			card->devname);
551		return -EINVAL;
552	}
553
554	/* allocate and initialize private data */
555	chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
556
557	if(chdlc_priv_area == NULL)
558		return -ENOMEM;
559
560	memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
561
562	chdlc_priv_area->card = card;
563
564	/* initialize data */
565	strcpy(card->u.c.if_name, conf->name);
566
567	if(card->wandev.new_if_cnt > 0) {
568                kfree(chdlc_priv_area);
569		return -EEXIST;
570	}
571
572	card->wandev.new_if_cnt++;
573
574	chdlc_priv_area->TracingEnabled = 0;
575
576	//We don't need this any more
577	chdlc_priv_area->route_status = NO_ROUTE;
578	chdlc_priv_area->route_removed = 0;
579
580	printk(KERN_INFO "%s: Firmware running in HDLC STREAMING Mode\n",
581		wandev->name);
582
583	/* Setup wanpipe as a router (WANPIPE) or as an API */
584	if( strcmp(conf->usedby, "WANPIPE") == 0) {
585		printk(KERN_INFO "%s: Driver running in WANPIPE mode!\n",
586			wandev->name);
587		card->u.c.usedby = WANPIPE;
588	} else {
589		printk(KERN_INFO
590			"%s: API Mode is not supported for SyncPPP!\n",
591			wandev->name);
592		kfree(chdlc_priv_area);
593		return -EINVAL;
594	}
595
596	/* Get Multicast Information */
597	chdlc_priv_area->mc = conf->mc;
598
599
600	chdlc_priv_area->if_ptr = pppdev;
601
602	/* prepare network device data space for registration */
603
604#ifdef LINUX_2_4
605	strcpy(dev->name,card->u.c.if_name);
606#else
607	dev->name = (char *)kmalloc(strlen(card->u.c.if_name) + 2, GFP_KERNEL);
608	if(dev->name == NULL)
609	{
610		kfree(chdlc_priv_area);
611		return -ENOMEM;
612	}
613	sprintf(dev->name, "%s", card->u.c.if_name);
614#endif
615
616	/* Attach PPP protocol layer to pppdev
617	 * The sppp_attach() will initilize the dev structure
618         * and setup ppp layer protocols.
619         * All we have to do is to bind in:
620         *        if_open(), if_close(), if_send() and get_stats() functions.
621         */
622	sppp_attach(pppdev);
623#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,16)
624	dev = pppdev->dev;
625#else
626	dev = &pppdev->dev;
627#endif
628	sp = &pppdev->sppp;
629
630	/* Enable PPP Debugging */
631	// FIXME Fix this up somehow
632	//sp->pp_flags |= PP_DEBUG;
633	sp->pp_flags &= ~PP_CISCO;
634
635	dev->init = &if_init;
636	dev->priv = chdlc_priv_area;
637
638	return 0;
639}
640
641
642
643
644/*============================================================================
645 * Delete logical channel.
646 */
647static int del_if (wan_device_t* wandev, netdevice_t* dev)
648{
649	chdlc_private_area_t *chdlc_priv_area = dev->priv;
650	sdla_t *card = chdlc_priv_area->card;
651	unsigned long smp_lock;
652
653	/* Detach the PPP layer */
654	printk(KERN_INFO "%s: Detaching SyncPPP Module from %s\n",
655			wandev->name,dev->name);
656
657	lock_adapter_irq(&wandev->lock,&smp_lock);
658
659	sppp_detach(dev);
660	chdlc_priv_area->if_ptr=NULL;
661
662	chdlc_set_intr_mode(card, 0);
663	if (card->u.c.comm_enabled)
664		chdlc_comm_disable(card);
665	unlock_adapter_irq(&wandev->lock,&smp_lock);
666
667	port_set_state(card, WAN_DISCONNECTED);
668
669	return 0;
670}
671
672
673/****** Network Device Interface ********************************************/
674
675/*============================================================================
676 * Initialize Linux network interface.
677 *
678 * This routine is called only once for each interface, during Linux network
679 * interface registration.  Returning anything but zero will fail interface
680 * registration.
681 */
682static int if_init (netdevice_t* dev)
683	{
684	chdlc_private_area_t* chdlc_priv_area = dev->priv;
685	sdla_t* card = chdlc_priv_area->card;
686	wan_device_t* wandev = &card->wandev;
687#ifdef LINUX_2_0
688	int i;
689#endif
690
691	/* NOTE: Most of the dev initialization was
692         *       done in sppp_attach(), called by new_if()
693         *       function. All we have to do here is
694         *       to link four major routines below.
695         */
696
697	/* Initialize device driver entry points */
698	dev->open		= &if_open;
699	dev->stop		= &if_close;
700	dev->hard_start_xmit	= &if_send;
701	dev->get_stats		= &if_stats;
702#ifdef LINUX_2_4
703	dev->tx_timeout		= &if_tx_timeout;
704	dev->watchdog_timeo	= TX_TIMEOUT;
705#endif
706
707
708#ifdef LINUX_2_0
709	dev->family		= AF_INET;
710#endif
711
712	/* Initialize hardware parameters */
713	dev->irq	= wandev->irq;
714	dev->dma	= wandev->dma;
715	dev->base_addr	= wandev->ioport;
716	dev->mem_start	= wandev->maddr;
717	dev->mem_end	= wandev->maddr + wandev->msize - 1;
718
719	/* Set transmit buffer queue length
720         * If we over fill this queue the packets will
721         * be droped by the kernel.
722         * sppp_attach() sets this to 10, but
723         * 100 will give us more room at low speeds.
724	 */
725        dev->tx_queue_len = 100;
726
727	/* Initialize socket buffers */
728#if !defined(LINUX_2_1) && !defined(LINUX_2_4)
729        for (i = 0; i < DEV_NUMBUFFS; ++i)
730                skb_queue_head_init(&dev->buffs[i]);
731#endif
732
733	return 0;
734}
735
736
737#ifdef LINUX_2_4
738/*============================================================================
739 * Handle transmit timeout event from netif watchdog
740 */
741static void if_tx_timeout (netdevice_t *dev)
742{
743    	chdlc_private_area_t* chan = dev->priv;
744	sdla_t *card = chan->card;
745
746	/* If our device stays busy for at least 5 seconds then we will
747	 * kick start the device by making dev->tbusy = 0.  We expect
748	 * that our device never stays busy more than 5 seconds. So this
749	 * is only used as a last resort.
750	 */
751
752	++card->wandev.stats.collisions;
753
754	printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
755	netif_wake_queue (dev);
756}
757#endif
758
759
760
761/*============================================================================
762 * Open network interface.
763 * o enable communications and interrupts.
764 * o prevent module from unloading by incrementing use count
765 *
766 * Return 0 if O.k. or errno.
767 */
768static int if_open (netdevice_t* dev)
769{
770	chdlc_private_area_t* chdlc_priv_area = dev->priv;
771	sdla_t* card = chdlc_priv_area->card;
772	struct timeval tv;
773	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
774
775	/* Only one open per interface is allowed */
776
777#ifdef LINUX_2_4
778	if (netif_running(dev))
779		return -EBUSY;
780#else
781	if (dev->start)
782		return -EBUSY;		/* only one open is allowed */
783#endif
784
785	/* Start PPP Layer */
786	if (sppp_open(dev)){
787		return -EIO;
788	}
789
790	do_gettimeofday(&tv);
791	chdlc_priv_area->router_start_time = tv.tv_sec;
792
793#ifdef LINUX_2_4
794	netif_start_queue(dev);
795#else
796	dev->interrupt = 0;
797	dev->tbusy = 0;
798	dev->start = 1;
799#endif
800
801	wanpipe_open(card);
802
803	chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
804	flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
805	return 0;
806}
807
808/*============================================================================
809 * Close network interface.
810 * o if this is the last close, then disable communications and interrupts.
811 * o reset flags.
812 */
813static int if_close (netdevice_t* dev)
814{
815	chdlc_private_area_t* chdlc_priv_area = dev->priv;
816	sdla_t* card = chdlc_priv_area->card;
817
818	/* Stop the PPP Layer */
819	sppp_close(dev);
820	stop_net_queue(dev);
821
822#ifndef LINUX_2_4
823	dev->start=0;
824#endif
825
826	wanpipe_close(card);
827
828	return 0;
829}
830
831/*============================================================================
832 * Send a packet on a network interface.
833 * o set tbusy flag (marks start of the transmission) to block a timer-based
834 *   transmit from overlapping.
835 * o check link state. If link is not up, then drop the packet.
836 * o execute adapter send command.
837 * o free socket buffer
838 *
839 * Return:	0	complete (socket buffer must be freed)
840 *		non-0	packet may be re-transmitted (tbusy must be set)
841 *
842 * Notes:
843 * 1. This routine is called either by the protocol stack or by the "net
844 *    bottom half" (with interrupts enabled).
845 * 2. Setting tbusy flag will inhibit further transmit requests from the
846 *    protocol stack and can be used for flow control with protocol layer.
847 */
848static int if_send (struct sk_buff* skb, netdevice_t* dev)
849{
850	chdlc_private_area_t *chdlc_priv_area = dev->priv;
851	sdla_t *card = chdlc_priv_area->card;
852	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
853	INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
854	int udp_type = 0;
855	unsigned long smp_flags;
856	int err=0;
857
858#ifdef LINUX_2_4
859	netif_stop_queue(dev);
860#endif
861
862
863	if (skb == NULL){
864		/* If we get here, some higher layer thinks we've missed an
865		 * tx-done interrupt.
866		 */
867		printk(KERN_INFO "%s: Received NULL skb buffer! interface %s got kicked!\n",
868			card->devname, dev->name);
869
870		wake_net_dev(dev);
871		return 0;
872	}
873
874#ifndef LINUX_2_4
875	if (dev->tbusy){
876
877		/* If our device stays busy for at least 5 seconds then we will
878		 * kick start the device by making dev->tbusy = 0.  We expect
879		 * that our device never stays busy more than 5 seconds. So this
880		 * is only used as a last resort.
881		 */
882                ++card->wandev.stats.collisions;
883
884		if((jiffies - chdlc_priv_area->tick_counter) < (5 * HZ)) {
885			return 1;
886		}
887
888		printk (KERN_INFO "%s: Transmit (tbusy) timeout !\n",
889			card->devname);
890
891		/* unbusy the interface */
892		dev->tbusy = 0;
893	}
894#endif
895
896   	if (ntohs(skb->protocol) != htons(PVC_PROT)){
897		/* check the udp packet type */
898
899		udp_type = udp_pkt_type(skb, card);
900		if (udp_type == UDP_CPIPE_TYPE){
901                        if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
902                                chdlc_priv_area)){
903				chdlc_int->interrupt_permission |=
904					APP_INT_ON_TIMER;
905			}
906			start_net_queue(dev);
907			return 0;
908		}
909        }
910
911	/* Lock the 508 Card: SMP is supported */
912      	if(card->hw.type != SDLA_S514){
913		s508_lock(card,&smp_flags);
914	}
915
916    	if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)){
917
918		printk(KERN_INFO "%s: Critical in if_send: %lx\n",
919					card->wandev.name,card->wandev.critical);
920                ++card->wandev.stats.tx_dropped;
921		start_net_queue(dev);
922		goto if_send_crit_exit;
923	}
924
925	if (card->wandev.state != WAN_CONNECTED){
926		++card->wandev.stats.tx_dropped;
927		start_net_queue(dev);
928		goto if_send_crit_exit;
929	}
930
931	if (chdlc_send(card, skb->data, skb->len)){
932		stop_net_queue(dev);
933
934	}else{
935		++card->wandev.stats.tx_packets;
936#if defined(LINUX_2_1) || defined(LINUX_2_4)
937       		card->wandev.stats.tx_bytes += skb->len;
938#endif
939#ifdef LINUX_2_4
940		dev->trans_start = jiffies;
941#endif
942		start_net_queue(dev);
943	}
944
945if_send_crit_exit:
946	if (!(err=is_queue_stopped(dev))){
947                wan_dev_kfree_skb(skb, FREE_WRITE);
948	}else{
949		chdlc_priv_area->tick_counter = jiffies;
950		chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
951	}
952
953	clear_bit(SEND_CRIT, (void*)&card->wandev.critical);
954	if(card->hw.type != SDLA_S514){
955		s508_unlock(card,&smp_flags);
956	}
957
958	return err;
959}
960
961
962/*============================================================================
963 * Reply to UDP Management system.
964 * Return length of reply.
965 */
966static int reply_udp( unsigned char *data, unsigned int mbox_len )
967{
968
969	unsigned short len, udp_length, temp, ip_length;
970	unsigned long ip_temp;
971	int even_bound = 0;
972  	chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data;
973
974	/* Set length of packet */
975	len = sizeof(ip_pkt_t)+
976	      sizeof(udp_pkt_t)+
977	      sizeof(wp_mgmt_t)+
978	      sizeof(cblock_t)+
979	      sizeof(trace_info_t)+
980	      mbox_len;
981
982	/* fill in UDP reply */
983	c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
984
985	/* fill in UDP length */
986	udp_length = sizeof(udp_pkt_t)+
987		     sizeof(wp_mgmt_t)+
988		     sizeof(cblock_t)+
989	             sizeof(trace_info_t)+
990		     mbox_len;
991
992 	/* put it on an even boundary */
993	if ( udp_length & 0x0001 ) {
994		udp_length += 1;
995		len += 1;
996		even_bound = 1;
997	}
998
999	temp = (udp_length<<8)|(udp_length>>8);
1000	c_udp_pkt->udp_pkt.udp_length = temp;
1001
1002	/* swap UDP ports */
1003	temp = c_udp_pkt->udp_pkt.udp_src_port;
1004	c_udp_pkt->udp_pkt.udp_src_port =
1005			c_udp_pkt->udp_pkt.udp_dst_port;
1006	c_udp_pkt->udp_pkt.udp_dst_port = temp;
1007
1008	/* add UDP pseudo header */
1009	temp = 0x1100;
1010	*((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp;
1011	temp = (udp_length<<8)|(udp_length>>8);
1012	*((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp;
1013
1014
1015	/* calculate UDP checksum */
1016	c_udp_pkt->udp_pkt.udp_checksum = 0;
1017	c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
1018
1019	/* fill in IP length */
1020	ip_length = len;
1021	temp = (ip_length<<8)|(ip_length>>8);
1022	c_udp_pkt->ip_pkt.total_length = temp;
1023
1024	/* swap IP addresses */
1025	ip_temp = c_udp_pkt->ip_pkt.ip_src_address;
1026	c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address;
1027	c_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
1028
1029	/* fill in IP checksum */
1030	c_udp_pkt->ip_pkt.hdr_checksum = 0;
1031	c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));
1032
1033	return len;
1034
1035} /* reply_udp */
1036
1037unsigned short calc_checksum (char *data, int len)
1038{
1039	unsigned short temp;
1040	unsigned long sum=0;
1041	int i;
1042
1043	for( i = 0; i <len; i+=2 ) {
1044		memcpy(&temp,&data[i],2);
1045		sum += (unsigned long)temp;
1046	}
1047
1048	while (sum >> 16 ) {
1049		sum = (sum & 0xffffUL) + (sum >> 16);
1050	}
1051
1052	temp = (unsigned short)sum;
1053	temp = ~temp;
1054
1055	if( temp == 0 )
1056		temp = 0xffff;
1057
1058	return temp;
1059}
1060
1061
1062/*============================================================================
1063 * Get ethernet-style interface statistics.
1064 * Return a pointer to struct enet_statistics.
1065 */
1066#if defined(LINUX_2_1) || defined(LINUX_2_4)
1067static struct net_device_stats* if_stats (netdevice_t* dev)
1068{
1069	sdla_t *my_card;
1070	chdlc_private_area_t* chdlc_priv_area;
1071
1072	/* Shutdown bug fix. In del_if() we kill
1073         * dev->priv pointer. This function, gets
1074         * called after del_if(), thus check
1075         * if pointer has been deleted */
1076	if ((chdlc_priv_area=dev->priv) == NULL)
1077		return NULL;
1078
1079	my_card = chdlc_priv_area->card;
1080	return &my_card->wandev.stats;
1081}
1082#else
1083static struct enet_statistics* if_stats (netdevice_t* dev)
1084{
1085        sdla_t *my_card;
1086        chdlc_private_area_t* chdlc_priv_area = dev->priv;
1087
1088	/* Shutdown bug fix. In del_if() we kill
1089         * dev->priv pointer. This function, gets
1090         * called after del_if(), thus check
1091         * if pointer has been deleted */
1092	if ((chdlc_priv_area=dev->priv) == NULL)
1093		return NULL;
1094
1095        my_card = chdlc_priv_area->card;
1096        return &my_card->wandev.stats;
1097}
1098#endif
1099
1100/****** Cisco HDLC Firmware Interface Functions *******************************/
1101
1102/*============================================================================
1103 * Read firmware code version.
1104 *	Put code version as ASCII string in str.
1105 */
1106static int chdlc_read_version (sdla_t* card, char* str)
1107{
1108	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1109	int len;
1110	char err;
1111	mb->buffer_length = 0;
1112	mb->command = READ_CHDLC_CODE_VERSION;
1113	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1114
1115	if(err != COMMAND_OK) {
1116		chdlc_error(card,err,mb);
1117	}
1118	else if (str) {  /* is not null */
1119		len = mb->buffer_length;
1120		memcpy(str, mb->data, len);
1121		str[len] = '\0';
1122	}
1123	return (err);
1124}
1125
1126/*-----------------------------------------------------------------------------
1127 *  Configure CHDLC firmware.
1128 */
1129static int chdlc_configure (sdla_t* card, void* data)
1130{
1131	int err;
1132	CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
1133	int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);
1134
1135	mailbox->buffer_length = data_length;
1136	memcpy(mailbox->data, data, data_length);
1137	mailbox->command = SET_CHDLC_CONFIGURATION;
1138	err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
1139
1140	if (err != COMMAND_OK) chdlc_error (card, err, mailbox);
1141
1142	return err;
1143}
1144
1145
1146/*============================================================================
1147 * Set interrupt mode -- HDLC Version.
1148 */
1149
1150static int chdlc_set_intr_mode (sdla_t* card, unsigned mode)
1151{
1152	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1153	CHDLC_INT_TRIGGERS_STRUCT* int_data =
1154		 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1155	int err;
1156
1157	int_data->CHDLC_interrupt_triggers 	= mode;
1158	int_data->IRQ				= card->hw.irq;
1159	int_data->interrupt_timer               = 1;
1160
1161	mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
1162	mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
1163	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1164	if (err != COMMAND_OK)
1165		chdlc_error (card, err, mb);
1166	return err;
1167}
1168
1169
1170/*============================================================================
1171 * Enable communications.
1172 */
1173
1174static int chdlc_comm_enable (sdla_t* card)
1175{
1176	int err;
1177	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1178
1179	mb->buffer_length = 0;
1180	mb->command = ENABLE_CHDLC_COMMUNICATIONS;
1181	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1182	if (err != COMMAND_OK)
1183		chdlc_error(card, err, mb);
1184	else
1185		card->u.c.comm_enabled=1;
1186
1187	return err;
1188}
1189
1190/*============================================================================
1191 * Disable communications and Drop the Modem lines (DCD and RTS).
1192 */
1193static int chdlc_comm_disable (sdla_t* card)
1194{
1195	int err;
1196	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1197
1198	mb->buffer_length = 0;
1199	mb->command = DISABLE_CHDLC_COMMUNICATIONS;
1200	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1201	if (err != COMMAND_OK)
1202		chdlc_error(card,err,mb);
1203
1204	return err;
1205}
1206
1207/*============================================================================
1208 * Read communication error statistics.
1209 */
1210static int chdlc_read_comm_err_stats (sdla_t* card)
1211{
1212        int err;
1213        CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1214
1215        mb->buffer_length = 0;
1216        mb->command = READ_COMMS_ERROR_STATS;
1217        err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1218        if (err != COMMAND_OK)
1219                chdlc_error(card,err,mb);
1220        return err;
1221}
1222
1223
1224/*============================================================================
1225 * Read CHDLC operational statistics.
1226 */
1227static int chdlc_read_op_stats (sdla_t* card)
1228{
1229        int err;
1230        CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1231
1232        mb->buffer_length = 0;
1233        mb->command = READ_CHDLC_OPERATIONAL_STATS;
1234        err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1235        if (err != COMMAND_OK)
1236                chdlc_error(card,err,mb);
1237        return err;
1238}
1239
1240
1241/*============================================================================
1242 * Update communications error and general packet statistics.
1243 */
1244static int update_comms_stats(sdla_t* card,
1245	chdlc_private_area_t* chdlc_priv_area)
1246{
1247        CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1248  	COMMS_ERROR_STATS_STRUCT* err_stats;
1249        CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;
1250
1251	/* on the first timer interrupt, read the comms error statistics */
1252	if(chdlc_priv_area->update_comms_stats == 2) {
1253		if(chdlc_read_comm_err_stats(card))
1254			return 1;
1255		err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data;
1256		card->wandev.stats.rx_over_errors =
1257				err_stats->Rx_overrun_err_count;
1258		card->wandev.stats.rx_crc_errors =
1259				err_stats->CRC_err_count;
1260		card->wandev.stats.rx_frame_errors =
1261				err_stats->Rx_abort_count;
1262		card->wandev.stats.rx_fifo_errors =
1263				err_stats->Rx_dis_pri_bfrs_full_count;
1264		card->wandev.stats.rx_missed_errors =
1265				card->wandev.stats.rx_fifo_errors;
1266		card->wandev.stats.tx_aborted_errors =
1267				err_stats->sec_Tx_abort_count;
1268	}
1269
1270        /* on the second timer interrupt, read the operational statistics */
1271	else {
1272        	if(chdlc_read_op_stats(card))
1273                	return 1;
1274		op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data;
1275		card->wandev.stats.rx_length_errors =
1276			(op_stats->Rx_Data_discard_short_count +
1277			op_stats->Rx_Data_discard_long_count);
1278	}
1279
1280	return 0;
1281}
1282
1283/*============================================================================
1284 * Send packet.
1285 *	Return:	0 - o.k.
1286 *		1 - no transmit buffers available
1287 */
1288static int chdlc_send (sdla_t* card, void* data, unsigned len)
1289{
1290	CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;
1291
1292	if (txbuf->opp_flag)
1293		return 1;
1294
1295	sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);
1296
1297	txbuf->frame_length = len;
1298	txbuf->opp_flag = 1;		/* start transmission */
1299
1300	/* Update transmit buffer control fields */
1301	card->u.c.txbuf = ++txbuf;
1302
1303	if ((void*)txbuf > card->u.c.txbuf_last)
1304		card->u.c.txbuf = card->u.c.txbuf_base;
1305
1306	return 0;
1307}
1308
1309/****** Firmware Error Handler **********************************************/
1310
1311/*============================================================================
1312 * Firmware error handler.
1313 *	This routine is called whenever firmware command returns non-zero
1314 *	return code.
1315 *
1316 * Return zero if previous command has to be cancelled.
1317 */
1318static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
1319{
1320	unsigned cmd = mb->command;
1321
1322	switch (err) {
1323
1324	case CMD_TIMEOUT:
1325		printk(KERN_ERR "%s: command 0x%02X timed out!\n",
1326			card->devname, cmd);
1327		break;
1328
1329	case S514_BOTH_PORTS_SAME_CLK_MODE:
1330		if(cmd == SET_CHDLC_CONFIGURATION) {
1331			printk(KERN_INFO
1332			 "%s: Configure both ports for the same clock source\n",
1333				card->devname);
1334			break;
1335		}
1336
1337	default:
1338		printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
1339			card->devname, cmd, err);
1340	}
1341
1342	return 0;
1343}
1344
1345/****** Interrupt Handlers **************************************************/
1346
1347/*============================================================================
1348 * Cisco HDLC interrupt service routine.
1349 */
1350STATIC void wsppp_isr (sdla_t* card)
1351{
1352	netdevice_t* dev;
1353	SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1354	int i;
1355	sdla_t *my_card;
1356
1357
1358	/* Check for which port the interrupt has been generated
1359	 * Since Secondary Port is piggybacking on the Primary
1360         * the check must be done here.
1361	 */
1362
1363	flags = card->u.c.flags;
1364	if (!flags->interrupt_info_struct.interrupt_type){
1365		/* Check for a second port (piggybacking) */
1366		if((my_card = card->next)){
1367			flags = my_card->u.c.flags;
1368			if (flags->interrupt_info_struct.interrupt_type){
1369				card = my_card;
1370				card->isr(card);
1371				return;
1372			}
1373		}
1374	}
1375
1376	dev = card->wandev.dev;
1377	card->in_isr = 1;
1378	flags = card->u.c.flags;
1379
1380	/* If we get an interrupt with no network device, stop the interrupts
1381	 * and issue an error */
1382	if ((!dev || !dev->priv) && flags->interrupt_info_struct.interrupt_type !=
1383	    	COMMAND_COMPLETE_APP_INT_PEND){
1384		goto isr_done;
1385	}
1386
1387
1388	/* if critical due to peripheral operations
1389	 * ie. update() or getstats() then reset the interrupt and
1390	 * wait for the board to retrigger.
1391	 */
1392	if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
1393		flags->interrupt_info_struct.
1394					interrupt_type = 0;
1395		goto isr_done;
1396	}
1397
1398
1399	/* On a 508 Card, if critical due to if_send
1400         * Major Error !!!
1401	 */
1402	if(card->hw.type != SDLA_S514) {
1403		if(test_bit(0, (void*)&card->wandev.critical)) {
1404			printk(KERN_INFO "%s: Critical while in ISR: %lx\n",
1405				card->devname, card->wandev.critical);
1406			goto isr_done;
1407		}
1408	}
1409
1410	switch(flags->interrupt_info_struct.interrupt_type) {
1411
1412		case RX_APP_INT_PEND:	/* 0x01: receive interrupt */
1413			rx_intr(card);
1414			break;
1415
1416		case TX_APP_INT_PEND:	/* 0x02: transmit interrupt */
1417			flags->interrupt_info_struct.interrupt_permission &=
1418				 ~APP_INT_ON_TX_FRAME;
1419
1420			wake_net_dev(dev);
1421			break;
1422
1423		case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
1424			++ Intr_test_counter;
1425			break;
1426
1427		case CHDLC_EXCEP_COND_APP_INT_PEND:	/* 0x20 */
1428			process_chdlc_exception(card);
1429			break;
1430
1431		case GLOBAL_EXCEP_COND_APP_INT_PEND:
1432			process_global_exception(card);
1433			break;
1434
1435		case TIMER_APP_INT_PEND:
1436			timer_intr(card);
1437			break;
1438
1439		default:
1440			printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n",
1441				card->devname,
1442				flags->interrupt_info_struct.interrupt_type);
1443			printk(KERN_INFO "Code name: ");
1444			for(i = 0; i < 4; i ++)
1445				printk(KERN_INFO "%c",
1446					flags->global_info_struct.codename[i]);
1447			printk(KERN_INFO "\nCode version: ");
1448			for(i = 0; i < 4; i ++)
1449				printk(KERN_INFO "%c",
1450					flags->global_info_struct.codeversion[i]);
1451			printk(KERN_INFO "\n");
1452			break;
1453	}
1454
1455isr_done:
1456	card->in_isr = 0;
1457	flags->interrupt_info_struct.interrupt_type = 0;
1458}
1459
1460/*============================================================================
1461 * Receive interrupt handler.
1462 */
1463static void rx_intr (sdla_t* card)
1464{
1465	netdevice_t *dev;
1466	chdlc_private_area_t *chdlc_priv_area;
1467	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1468	CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
1469	struct sk_buff *skb;
1470	unsigned len;
1471	unsigned addr = rxbuf->ptr_data_bfr;
1472	void *buf;
1473	int i,udp_type;
1474
1475	if (rxbuf->opp_flag != 0x01) {
1476		printk(KERN_INFO
1477			"%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
1478			card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
1479                printk(KERN_INFO "Code name: ");
1480                for(i = 0; i < 4; i ++)
1481                        printk(KERN_INFO "%c",
1482                                flags->global_info_struct.codename[i]);
1483                printk(KERN_INFO "\nCode version: ");
1484                for(i = 0; i < 4; i ++)
1485                        printk(KERN_INFO "%c",
1486                                flags->global_info_struct.codeversion[i]);
1487                printk(KERN_INFO "\n");
1488
1489
1490		/* Bug Fix: Mar 6 2000
1491                 * If we get a corrupted mailbox, it measn that driver
1492                 * is out of sync with the firmware. There is no recovery.
1493                 * If we don't turn off all interrupts for this card
1494                 * the machine will crash.
1495                 */
1496		printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
1497		printk(KERN_INFO "Please contact Sangoma Technologies !\n");
1498		chdlc_set_intr_mode(card,0);
1499		return;
1500	}
1501
1502	dev = card->wandev.dev;
1503
1504	if (!dev){
1505		goto rx_exit;
1506	}
1507
1508#ifdef LINUX_2_4
1509	if (!netif_running(dev)){
1510		goto rx_exit;
1511	}
1512#else
1513	if (!dev->start){
1514		goto rx_exit;
1515	}
1516#endif
1517
1518	chdlc_priv_area = dev->priv;
1519
1520	if (rxbuf->error_flag){
1521		goto rx_exit;
1522	}
1523	/* Take off two CRC bytes */
1524
1525	if (rxbuf->frame_length < 7 || rxbuf->frame_length > 1506 ){
1526		goto rx_exit;
1527	}
1528
1529	len = rxbuf->frame_length - CRC_LENGTH;
1530
1531	/* Allocate socket buffer */
1532	skb = dev_alloc_skb(len);
1533
1534	if (skb == NULL) {
1535		if (net_ratelimit()){
1536			printk(KERN_INFO "%s: no socket buffers available!\n",
1537						card->devname);
1538		}
1539		++card->wandev.stats.rx_dropped;
1540		goto rx_exit;
1541	}
1542
1543	/* Copy data to the socket buffer */
1544	if((addr + len) > card->u.c.rx_top + 1) {
1545		unsigned tmp = card->u.c.rx_top - addr + 1;
1546		buf = skb_put(skb, tmp);
1547		sdla_peek(&card->hw, addr, buf, tmp);
1548		addr = card->u.c.rx_base;
1549		len -= tmp;
1550	}
1551
1552	buf = skb_put(skb, len);
1553	sdla_peek(&card->hw, addr, buf, len);
1554
1555	skb->protocol = htons(ETH_P_WAN_PPP);
1556
1557	card->wandev.stats.rx_packets ++;
1558#if defined(LINUX_2_1) || defined(LINUX_2_4)
1559	card->wandev.stats.rx_bytes += skb->len;
1560#endif
1561	udp_type = udp_pkt_type( skb, card );
1562
1563	if(udp_type == UDP_CPIPE_TYPE) {
1564		if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
1565   				      card, skb, dev, chdlc_priv_area)) {
1566     		        flags->interrupt_info_struct.
1567						interrupt_permission |=
1568							APP_INT_ON_TIMER;
1569		}
1570	}else{
1571               	/* Pass it up the protocol stack */
1572                skb->dev = dev;
1573                skb->mac.raw  = skb->data;
1574                netif_rx(skb);
1575	}
1576
1577rx_exit:
1578	/* Release buffer element and calculate a pointer to the next one */
1579	rxbuf->opp_flag = 0x00;
1580	card->u.c.rxmb = ++ rxbuf;
1581	if((void*)rxbuf > card->u.c.rxbuf_last){
1582		card->u.c.rxmb = card->u.c.rxbuf_base;
1583	}
1584}
1585
1586/*============================================================================
1587 * Timer interrupt handler.
1588 * The timer interrupt is used for two purposes:
1589 *    1) Processing udp calls from 'cpipemon'.
1590 *    2) Reading board-level statistics for updating the proc file system.
1591 */
1592void timer_intr(sdla_t *card)
1593{
1594        netdevice_t* dev;
1595        chdlc_private_area_t* chdlc_priv_area = NULL;
1596        SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1597
1598        dev = card->wandev.dev;
1599        chdlc_priv_area = dev->priv;
1600
1601	if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) {
1602		if (!config_chdlc(card)){
1603			chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
1604		}
1605	}
1606
1607	/* process a udp call if pending */
1608       	if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
1609               	process_udp_mgmt_pkt(card, dev,
1610                       chdlc_priv_area);
1611		chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
1612        }
1613
1614
1615	/* read the communications statistics if required */
1616	if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
1617		update_comms_stats(card, chdlc_priv_area);
1618                if(!(-- chdlc_priv_area->update_comms_stats)) {
1619			chdlc_priv_area->timer_int_enabled &=
1620				~TMR_INT_ENABLED_UPDATE;
1621		}
1622        }
1623
1624	/* only disable the timer interrupt if there are no udp or statistic */
1625	/* updates pending */
1626        if(!chdlc_priv_area->timer_int_enabled) {
1627                flags = card->u.c.flags;
1628                flags->interrupt_info_struct.interrupt_permission &=
1629                        ~APP_INT_ON_TIMER;
1630        }
1631}
1632
1633/*------------------------------------------------------------------------------
1634  Miscellaneous Functions
1635	- set_chdlc_config() used to set configuration options on the board
1636------------------------------------------------------------------------------*/
1637
1638static int set_chdlc_config(sdla_t* card)
1639{
1640
1641	CHDLC_CONFIGURATION_STRUCT cfg;
1642
1643	memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
1644
1645	if(card->wandev.clocking)
1646		cfg.baud_rate = card->wandev.bps;
1647
1648	cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
1649		INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
1650
1651	cfg.modem_config_options	= 0;
1652	//API OPTIONS
1653	cfg.CHDLC_API_options		= DISCARD_RX_ERROR_FRAMES;
1654	cfg.modem_status_timer		= 100;
1655	cfg.CHDLC_protocol_options	= HDLC_STREAMING_MODE;
1656	cfg.percent_data_buffer_for_Tx  = 50;
1657	cfg.CHDLC_statistics_options	= (CHDLC_TX_DATA_BYTE_COUNT_STAT |
1658		CHDLC_RX_DATA_BYTE_COUNT_STAT);
1659	cfg.max_CHDLC_data_field_length	= card->wandev.mtu;
1660
1661	cfg.transmit_keepalive_timer	= 0;
1662	cfg.receive_keepalive_timer	= 0;
1663	cfg.keepalive_error_tolerance	= 0;
1664	cfg.SLARP_request_timer		= 0;
1665
1666	cfg.IP_address		= 0;
1667	cfg.IP_netmask		= 0;
1668
1669	return chdlc_configure(card, &cfg);
1670}
1671
1672/*============================================================================
1673 * Process global exception condition
1674 */
1675static int process_global_exception(sdla_t *card)
1676{
1677	CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
1678	int err;
1679
1680	mbox->buffer_length = 0;
1681	mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
1682	err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
1683
1684	if(err != CMD_TIMEOUT ){
1685
1686		switch(mbox->return_code) {
1687
1688	      	case EXCEP_MODEM_STATUS_CHANGE:
1689
1690			printk(KERN_INFO "%s: Modem status change\n",
1691				card->devname);
1692
1693			switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
1694				case (DCD_HIGH):
1695					printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname);
1696					break;
1697				case (CTS_HIGH):
1698                                        printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname);
1699                                        break;
1700                                case ((DCD_HIGH | CTS_HIGH)):
1701                                        printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname);
1702                                        break;
1703				default:
1704                                        printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname);
1705                                        break;
1706			}
1707
1708			if (!(mbox->data[0] & DCD_HIGH) || !(mbox->data[0] & DCD_HIGH)){
1709				//printk(KERN_INFO "Sending TERM Request Manually !\n");
1710				send_ppp_term_request(card->wandev.dev);
1711			}
1712			break;
1713
1714                case EXCEP_TRC_DISABLED:
1715                        printk(KERN_INFO "%s: Line trace disabled\n",
1716				card->devname);
1717                        break;
1718
1719		case EXCEP_IRQ_TIMEOUT:
1720			printk(KERN_INFO "%s: IRQ timeout occurred\n",
1721				card->devname);
1722			break;
1723
1724                default:
1725                        printk(KERN_INFO "%s: Global exception %x\n",
1726				card->devname, mbox->return_code);
1727                        break;
1728                }
1729	}
1730	return 0;
1731}
1732
1733
1734/*============================================================================
1735 * Process chdlc exception condition
1736 */
1737static int process_chdlc_exception(sdla_t *card)
1738{
1739	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1740	int err;
1741
1742	mb->buffer_length = 0;
1743	mb->command = READ_CHDLC_EXCEPTION_CONDITION;
1744	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1745	if(err != CMD_TIMEOUT) {
1746
1747		switch (err) {
1748
1749		case EXCEP_LINK_ACTIVE:
1750			port_set_state(card, WAN_CONNECTED);
1751			break;
1752
1753		case EXCEP_LINK_INACTIVE_MODEM:
1754			port_set_state(card, WAN_DISCONNECTED);
1755			break;
1756
1757		case EXCEP_LOOPBACK_CONDITION:
1758			printk(KERN_INFO "%s: Loopback Condition Detected.\n",
1759						card->devname);
1760			break;
1761
1762		case NO_CHDLC_EXCEP_COND_TO_REPORT:
1763			printk(KERN_INFO "%s: No exceptions reported.\n",
1764						card->devname);
1765			break;
1766		default:
1767			printk(KERN_INFO "%s: Exception Condition %x!\n",
1768					card->devname,err);
1769			break;
1770		}
1771
1772	}
1773	return 0;
1774}
1775
1776
1777/*=============================================================================
1778 * Store a UDP management packet for later processing.
1779 */
1780
1781static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
1782                                struct sk_buff *skb, netdevice_t* dev,
1783                                chdlc_private_area_t* chdlc_priv_area )
1784{
1785	int udp_pkt_stored = 0;
1786
1787	if(!chdlc_priv_area->udp_pkt_lgth &&
1788	  (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
1789        	chdlc_priv_area->udp_pkt_lgth = skb->len;
1790		chdlc_priv_area->udp_pkt_src = udp_pkt_src;
1791       		memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
1792		chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
1793		udp_pkt_stored = 1;
1794	}
1795
1796	if(udp_pkt_src == UDP_PKT_FRM_STACK)
1797		wan_dev_kfree_skb(skb, FREE_WRITE);
1798	else
1799                wan_dev_kfree_skb(skb, FREE_READ);
1800
1801	return(udp_pkt_stored);
1802}
1803
1804
1805/*=============================================================================
1806 * Process UDP management packet.
1807 */
1808
1809static int process_udp_mgmt_pkt(sdla_t* card, netdevice_t* dev,
1810				chdlc_private_area_t* chdlc_priv_area )
1811{
1812	unsigned char *buf;
1813	unsigned int frames, len;
1814	struct sk_buff *new_skb;
1815	unsigned short buffer_length, real_len;
1816	unsigned long data_ptr;
1817	unsigned data_length;
1818	int udp_mgmt_req_valid = 1;
1819	CHDLC_MAILBOX_STRUCT *mb = card->mbox;
1820	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1821	chdlc_udp_pkt_t *chdlc_udp_pkt;
1822	struct timeval tv;
1823	int err;
1824	char ut_char;
1825
1826	chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
1827
1828	if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
1829
1830		switch(chdlc_udp_pkt->cblock.command) {
1831			case READ_GLOBAL_STATISTICS:
1832			case READ_MODEM_STATUS:
1833			case READ_CHDLC_LINK_STATUS:
1834			case CPIPE_ROUTER_UP_TIME:
1835			case READ_COMMS_ERROR_STATS:
1836			case READ_CHDLC_OPERATIONAL_STATS:
1837
1838			/* These two commands are executed for
1839			 * each request */
1840			case READ_CHDLC_CONFIGURATION:
1841			case READ_CHDLC_CODE_VERSION:
1842				udp_mgmt_req_valid = 1;
1843				break;
1844			default:
1845				udp_mgmt_req_valid = 0;
1846				break;
1847		}
1848	}
1849
1850  	if(!udp_mgmt_req_valid) {
1851
1852		/* set length to 0 */
1853		chdlc_udp_pkt->cblock.buffer_length = 0;
1854
1855    		/* set return code */
1856		chdlc_udp_pkt->cblock.return_code = 0xCD;
1857
1858		if (net_ratelimit()){
1859			printk(KERN_INFO
1860			"%s: Warning, Illegal UDP command attempted from network: %x\n",
1861			card->devname,chdlc_udp_pkt->cblock.command);
1862		}
1863
1864   	} else {
1865	   	unsigned long trace_status_cfg_addr = 0;
1866		TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
1867		TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
1868
1869		switch(chdlc_udp_pkt->cblock.command) {
1870
1871		case CPIPE_ENABLE_TRACING:
1872		     if (!chdlc_priv_area->TracingEnabled) {
1873
1874			/* OPERATE_DATALINE_MONITOR */
1875
1876			mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
1877			mb->command = SET_TRACE_CONFIGURATION;
1878
1879    			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
1880				trace_config = TRACE_ACTIVE;
1881			/* Trace delay mode is not used because it slows
1882			   down transfer and results in a standoff situation
1883			   when there is a lot of data */
1884
1885			/* Configure the Trace based on user inputs */
1886			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |=
1887					chdlc_udp_pkt->data[0];
1888
1889			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
1890			   trace_deactivation_timer = 4000;
1891
1892
1893			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1894			if (err != COMMAND_OK) {
1895				chdlc_error(card,err,mb);
1896				card->TracingEnabled = 0;
1897				chdlc_udp_pkt->cblock.return_code = err;
1898				mb->buffer_length = 0;
1899				break;
1900	    		}
1901
1902			/* Get the base address of the trace element list */
1903			mb->buffer_length = 0;
1904			mb->command = READ_TRACE_CONFIGURATION;
1905			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1906
1907			if (err != COMMAND_OK) {
1908				chdlc_error(card,err,mb);
1909				chdlc_priv_area->TracingEnabled = 0;
1910				chdlc_udp_pkt->cblock.return_code = err;
1911				mb->buffer_length = 0;
1912				break;
1913	    		}
1914
1915	   		trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
1916				mb->data) -> ptr_trace_stat_el_cfg_struct;
1917
1918			sdla_peek(&card->hw, trace_status_cfg_addr,
1919				 &trace_cfg_struct, sizeof(trace_cfg_struct));
1920
1921			chdlc_priv_area->start_trace_addr = trace_cfg_struct.
1922				base_addr_trace_status_elements;
1923
1924			chdlc_priv_area->number_trace_elements =
1925					trace_cfg_struct.number_trace_status_elements;
1926
1927			chdlc_priv_area->end_trace_addr = (unsigned long)
1928					((TRACE_STATUS_ELEMENT_STRUCT *)
1929					 chdlc_priv_area->start_trace_addr +
1930					 (chdlc_priv_area->number_trace_elements - 1));
1931
1932			chdlc_priv_area->base_addr_trace_buffer =
1933					trace_cfg_struct.base_addr_trace_buffer;
1934
1935			chdlc_priv_area->end_addr_trace_buffer =
1936					trace_cfg_struct.end_addr_trace_buffer;
1937
1938		    	chdlc_priv_area->curr_trace_addr =
1939					trace_cfg_struct.next_trace_element_to_use;
1940
1941	    		chdlc_priv_area->available_buffer_space = 2000 -
1942								  sizeof(ip_pkt_t) -
1943								  sizeof(udp_pkt_t) -
1944							      	  sizeof(wp_mgmt_t) -
1945								  sizeof(cblock_t) -
1946							          sizeof(trace_info_t);
1947	       	     }
1948		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1949		     mb->buffer_length = 0;
1950	       	     chdlc_priv_area->TracingEnabled = 1;
1951	       	     break;
1952
1953
1954		case CPIPE_DISABLE_TRACING:
1955		     if (chdlc_priv_area->TracingEnabled) {
1956
1957			/* OPERATE_DATALINE_MONITOR */
1958			mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
1959			mb->command = SET_TRACE_CONFIGURATION;
1960    			((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
1961				trace_config = TRACE_INACTIVE;
1962			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1963		     }
1964
1965		     chdlc_priv_area->TracingEnabled = 0;
1966		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1967		     mb->buffer_length = 0;
1968		     break;
1969
1970
1971		case CPIPE_GET_TRACE_INFO:
1972
1973		     if (!chdlc_priv_area->TracingEnabled) {
1974			chdlc_udp_pkt->cblock.return_code = 1;
1975			mb->buffer_length = 0;
1976			break;
1977		     }
1978
1979  		     chdlc_udp_pkt->trace_info.ismoredata = 0x00;
1980		     buffer_length = 0;	/* offset of packet already occupied */
1981
1982		     for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
1983
1984			trace_pkt_t *trace_pkt = (trace_pkt_t *)
1985				&chdlc_udp_pkt->data[buffer_length];
1986
1987			sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
1988			   	  (unsigned char *)&trace_element_struct,
1989			   	  sizeof(TRACE_STATUS_ELEMENT_STRUCT));
1990
1991     			if (trace_element_struct.opp_flag == 0x00) {
1992			 	break;
1993			}
1994
1995			/* get pointer to real data */
1996			data_ptr = trace_element_struct.ptr_data_bfr;
1997
1998			/* See if there is actual data on the trace buffer */
1999			if (data_ptr){
2000				data_length = trace_element_struct.trace_length;
2001			}else{
2002				data_length = 0;
2003				chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2004			}
2005
2006   			if( (chdlc_priv_area->available_buffer_space - buffer_length)
2007				< ( sizeof(trace_pkt_t) + data_length) ) {
2008
2009                            /* indicate there are more frames on board & exit */
2010				chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2011                               	break;
2012                         }
2013
2014			trace_pkt->status = trace_element_struct.trace_type;
2015
2016			trace_pkt->time_stamp =
2017				trace_element_struct.trace_time_stamp;
2018
2019			trace_pkt->real_length =
2020				trace_element_struct.trace_length;
2021
2022			/* see if we can fit the frame into the user buffer */
2023			real_len = trace_pkt->real_length;
2024
2025			if (data_ptr == 0) {
2026			     	trace_pkt->data_avail = 0x00;
2027			} else {
2028				unsigned tmp = 0;
2029
2030				/* get the data from circular buffer
2031				    must check for end of buffer */
2032			        trace_pkt->data_avail = 0x01;
2033
2034				if ((data_ptr + real_len) >
2035					     chdlc_priv_area->end_addr_trace_buffer + 1){
2036
2037				    	tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
2038				    	sdla_peek(&card->hw, data_ptr,
2039					       	  trace_pkt->data,tmp);
2040				    	data_ptr = chdlc_priv_area->base_addr_trace_buffer;
2041				}
2042
2043		        	sdla_peek(&card->hw, data_ptr,
2044					  &trace_pkt->data[tmp], real_len - tmp);
2045			}
2046
2047			/* zero the opp flag to show we got the frame */
2048			ut_char = 0x00;
2049			sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
2050
2051       			/* now move onto the next frame */
2052       			chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
2053
2054       			/* check if we went over the last address */
2055			if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
2056				chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
2057       			}
2058
2059            		if(trace_pkt->data_avail == 0x01) {
2060				buffer_length += real_len - 1;
2061			}
2062
2063	       	    	/* for the header */
2064	            	buffer_length += sizeof(trace_pkt_t);
2065
2066		     }  /* For Loop */
2067
2068		     if (frames == chdlc_priv_area->number_trace_elements){
2069			chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2070	             }
2071 		     chdlc_udp_pkt->trace_info.num_frames = frames;
2072
2073    		     mb->buffer_length = buffer_length;
2074		     chdlc_udp_pkt->cblock.buffer_length = buffer_length;
2075
2076		     chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2077
2078		     break;
2079
2080
2081		case CPIPE_FT1_READ_STATUS:
2082			((unsigned char *)chdlc_udp_pkt->data )[0] =
2083				flags->FT1_info_struct.parallel_port_A_input;
2084
2085			((unsigned char *)chdlc_udp_pkt->data )[1] =
2086				flags->FT1_info_struct.parallel_port_B_input;
2087
2088			chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2089			mb->buffer_length = 2;
2090			break;
2091
2092		case CPIPE_ROUTER_UP_TIME:
2093			do_gettimeofday( &tv );
2094			chdlc_priv_area->router_up_time = tv.tv_sec -
2095					chdlc_priv_area->router_start_time;
2096			*(unsigned long *)&chdlc_udp_pkt->data =
2097					chdlc_priv_area->router_up_time;
2098			mb->buffer_length = sizeof(unsigned long);
2099			break;
2100
2101   		case FT1_MONITOR_STATUS_CTRL:
2102			/* Enable FT1 MONITOR STATUS */
2103	        	if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||
2104				(chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
2105
2106			     	if( rCount++ != 0 ) {
2107					chdlc_udp_pkt->cblock.
2108					return_code = COMMAND_OK;
2109					mb->buffer_length = 1;
2110		  			break;
2111		    	     	}
2112	      		}
2113
2114	      		/* Disable FT1 MONITOR STATUS */
2115	      		if( chdlc_udp_pkt->data[0] == 0) {
2116
2117	      	   	     	if( --rCount != 0) {
2118		  			chdlc_udp_pkt->cblock.
2119					return_code = COMMAND_OK;
2120					mb->buffer_length = 1;
2121		  			break;
2122	   	    	     	}
2123	      		}
2124
2125		default:
2126			/* it's a board command */
2127			mb->command = chdlc_udp_pkt->cblock.command;
2128			mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
2129			if (mb->buffer_length) {
2130				memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
2131							data, mb->buffer_length);
2132	      		}
2133			/* run the command on the board */
2134			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2135			if (err != COMMAND_OK) {
2136				break;
2137			}
2138
2139			/* copy the result back to our buffer */
2140	         	memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t));
2141
2142			if (mb->buffer_length) {
2143	         		memcpy(&chdlc_udp_pkt->data, &mb->data,
2144								mb->buffer_length);
2145	      		}
2146
2147		} /* end of switch */
2148     	} /* end of else */
2149
2150     	/* Fill UDP TTL */
2151	chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
2152
2153     	len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
2154
2155     	if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
2156		if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
2157			++ card->wandev.stats.tx_packets;
2158#if defined(LINUX_2_1) || defined(LINUX_2_4)
2159			card->wandev.stats.tx_bytes += len;
2160#endif
2161		}
2162	} else {
2163
2164		/* Pass it up the stack
2165    		   Allocate socket buffer */
2166		if ((new_skb = dev_alloc_skb(len)) != NULL) {
2167			/* copy data into new_skb */
2168
2169 	    		buf = skb_put(new_skb, len);
2170  	    		memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
2171
2172            		/* Decapsulate pkt and pass it up the protocol stack */
2173	    		new_skb->protocol = htons(ETH_P_IP);
2174            		new_skb->dev = dev;
2175	    		new_skb->mac.raw  = new_skb->data;
2176
2177			netif_rx(new_skb);
2178		} else {
2179
2180			printk(KERN_INFO "%s: no socket buffers available!\n",
2181					card->devname);
2182  		}
2183    	}
2184
2185	chdlc_priv_area->udp_pkt_lgth = 0;
2186
2187	return 0;
2188}
2189
2190/*============================================================================
2191 * Initialize Receive and Transmit Buffers.
2192 */
2193
2194static void init_chdlc_tx_rx_buff( sdla_t* card, netdevice_t *dev )
2195{
2196	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2197	CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
2198	CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
2199	char err;
2200
2201	mb->buffer_length = 0;
2202	mb->command = READ_CHDLC_CONFIGURATION;
2203	err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2204
2205	if(err != COMMAND_OK) {
2206		chdlc_error(card,err,mb);
2207		return;
2208	}
2209
2210	if(card->hw.type == SDLA_S514) {
2211		tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
2212                (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
2213                            ptr_CHDLC_Tx_stat_el_cfg_struct));
2214        	rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
2215                (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
2216                            ptr_CHDLC_Rx_stat_el_cfg_struct));
2217
2218       		/* Setup Head and Tails for buffers */
2219        	card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
2220                tx_config->base_addr_Tx_status_elements);
2221        	card->u.c.txbuf_last =
2222		(CHDLC_DATA_TX_STATUS_EL_STRUCT *)
2223                card->u.c.txbuf_base +
2224		(tx_config->number_Tx_status_elements - 1);
2225
2226        	card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
2227                rx_config->base_addr_Rx_status_elements);
2228        	card->u.c.rxbuf_last =
2229		(CHDLC_DATA_RX_STATUS_EL_STRUCT *)
2230                card->u.c.rxbuf_base +
2231		(rx_config->number_Rx_status_elements - 1);
2232
2233 		/* Set up next pointer to be used */
2234        	card->u.c.txbuf = (void *)(card->hw.dpmbase +
2235                tx_config->next_Tx_status_element_to_use);
2236        	card->u.c.rxmb = (void *)(card->hw.dpmbase +
2237                rx_config->next_Rx_status_element_to_use);
2238	}
2239        else {
2240                tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
2241			(((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
2242			ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
2243
2244                rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
2245			(((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
2246			ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
2247
2248                /* Setup Head and Tails for buffers */
2249                card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
2250		(tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
2251                card->u.c.txbuf_last =
2252		(CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
2253		+ (tx_config->number_Tx_status_elements - 1);
2254                card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
2255		(rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
2256                card->u.c.rxbuf_last =
2257		(CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
2258		+ (rx_config->number_Rx_status_elements - 1);
2259
2260                 /* Set up next pointer to be used */
2261                card->u.c.txbuf = (void *)(card->hw.dpmbase +
2262		(tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
2263                card->u.c.rxmb = (void *)(card->hw.dpmbase +
2264		(rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
2265        }
2266
2267        /* Setup Actual Buffer Start and end addresses */
2268        card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
2269        card->u.c.rx_top  = rx_config->end_addr_Rx_buffer;
2270
2271}
2272
2273/*=============================================================================
2274 * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
2275 * _TEST_COUNTER times.
2276 */
2277static int intr_test( sdla_t* card)
2278{
2279	CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2280	int err,i;
2281
2282	Intr_test_counter = 0;
2283
2284	/* The critical flag is unset because during intialization (if_open)
2285	 * we want the interrupts to be enabled so that when the wpc_isr is
2286	 * called it does not exit due to critical flag set.
2287	 */
2288
2289	err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
2290
2291	if (err == CMD_OK) {
2292		for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {
2293			mb->buffer_length  = 0;
2294			mb->command = READ_CHDLC_CODE_VERSION;
2295			err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2296		}
2297	}
2298	else {
2299		return err;
2300	}
2301
2302	err = chdlc_set_intr_mode(card, 0);
2303
2304	if (err != CMD_OK)
2305		return err;
2306
2307	return 0;
2308}
2309
2310/*==============================================================================
2311 * Determine what type of UDP call it is. CPIPEAB ?
2312 */
2313static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
2314{
2315	 chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
2316
2317	if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
2318	   (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
2319	   (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
2320	   (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
2321		return UDP_CPIPE_TYPE;
2322	}
2323	else return UDP_INVALID_TYPE;
2324}
2325
2326/*============================================================================
2327 * Set PORT state.
2328 */
2329static void port_set_state (sdla_t *card, int state)
2330{
2331	netdevice_t *dev = card->wandev.dev;
2332	chdlc_private_area_t *chdlc_priv_area = dev->priv;
2333
2334        if (card->u.c.state != state)
2335        {
2336                switch (state)
2337                {
2338                case WAN_CONNECTED:
2339                        printk (KERN_INFO "%s: HDLC link connected!\n",
2340                                card->devname);
2341                      break;
2342
2343                case WAN_CONNECTING:
2344                        printk (KERN_INFO "%s: HDLC link connecting...\n",
2345                                card->devname);
2346                        break;
2347
2348                case WAN_DISCONNECTED:
2349                        printk (KERN_INFO "%s: HDLC link disconnected!\n",
2350                                card->devname);
2351                        break;
2352                }
2353
2354                card->wandev.state = card->u.c.state = state;
2355		chdlc_priv_area->common.state = state;
2356        }
2357}
2358
2359void s508_lock (sdla_t *card, unsigned long *smp_flags)
2360{
2361#if defined(__SMP__) || defined(LINUX_2_4)
2362	spin_lock_irqsave(&card->wandev.lock, *smp_flags);
2363        if (card->next){
2364		/* It is ok to use spin_lock here, since we
2365		 * already turned off interrupts */
2366        	spin_lock(&card->next->wandev.lock);
2367	}
2368#else
2369	disable_irq(card->hw.irq);
2370#endif
2371}
2372
2373void s508_unlock (sdla_t *card, unsigned long *smp_flags)
2374{
2375#if defined(__SMP__) || defined(LINUX_2_4)
2376	if (card->next){
2377		spin_unlock(&card->next->wandev.lock);
2378	}
2379	spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
2380#else
2381	enable_irq(card->hw.irq);
2382#endif
2383}
2384
2385
2386
2387/*===========================================================================
2388 * config_chdlc
2389 *
2390 *	Configure the chdlc protocol and enable communications.
2391 *
2392 *   	The if_open() function binds this function to the poll routine.
2393 *      Therefore, this function will run every time the chdlc interface
2394 *      is brought up. We cannot run this function from the if_open
2395 *      because if_open does not have access to the remote IP address.
2396 *
2397 *	If the communications are not enabled, proceed to configure
2398 *      the card and enable communications.
2399 *
2400 *      If the communications are enabled, it means that the interface
2401 *      was shutdown by ether the user or driver. In this case, we
2402 *      have to check that the IP addresses have not changed.  If
2403 *      the IP addresses have changed, we have to reconfigure the firmware
2404 *      and update the changed IP addresses.  Otherwise, just exit.
2405 *
2406 */
2407
2408static int config_chdlc (sdla_t *card)
2409{
2410	netdevice_t *dev = card->wandev.dev;
2411	SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
2412
2413	if (card->u.c.comm_enabled){
2414		chdlc_comm_disable(card);
2415		port_set_state(card, WAN_DISCONNECTED);
2416	}
2417
2418	if (set_chdlc_config(card)) {
2419		printk(KERN_INFO "%s: CHDLC Configuration Failed!\n",
2420				card->devname);
2421		return 0;
2422	}
2423	init_chdlc_tx_rx_buff(card, dev);
2424
2425	/* Set interrupt mode and mask */
2426        if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
2427                		APP_INT_ON_GLOBAL_EXCEP_COND |
2428                		APP_INT_ON_TX_FRAME |
2429                		APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
2430		printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
2431				card->devname);
2432		return 0;
2433        }
2434
2435
2436	/* Mask the Transmit and Timer interrupt */
2437	flags->interrupt_info_struct.interrupt_permission &=
2438		~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
2439
2440
2441	if (chdlc_comm_enable(card) != 0) {
2442		printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
2443				card->devname);
2444		flags->interrupt_info_struct.interrupt_permission = 0;
2445		card->u.c.comm_enabled=0;
2446		chdlc_set_intr_mode(card,0);
2447		return 0;
2448	}
2449
2450	/* Initialize Rx/Tx buffer control fields */
2451	port_set_state(card, WAN_CONNECTING);
2452	return 0;
2453}
2454
2455
2456static void send_ppp_term_request (netdevice_t *dev)
2457{
2458	struct sk_buff *new_skb;
2459	unsigned char *buf;
2460
2461	if ((new_skb = dev_alloc_skb(8)) != NULL) {
2462		/* copy data into new_skb */
2463
2464		buf = skb_put(new_skb, 8);
2465		sprintf(buf,"%c%c%c%c%c%c%c%c", 0xFF,0x03,0xC0,0x21,0x05,0x98,0x00,0x07);
2466
2467		/* Decapsulate pkt and pass it up the protocol stack */
2468		new_skb->protocol = htons(ETH_P_WAN_PPP);
2469		new_skb->dev = dev;
2470		new_skb->mac.raw  = new_skb->data;
2471
2472		netif_rx(new_skb);
2473	}
2474}
2475
2476
2477MODULE_LICENSE("GPL");
2478
2479/****** End ****************************************************************/
2480