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