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