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