[TG3]: Set minimal hw interrupt mitigation.
[linux-2.6/verdex.git] / drivers / net / wan / wanpipe_multppp.c
blob6aa6987d96cbf9aab2894b18ac03b14c063eef19
1 /*****************************************************************************
2 * wanpipe_multppp.c Multi-Port PPP driver module.
4 * Authors: Nenad Corbic <ncorbic@sangoma.com>
6 * Copyright: (c) 1995-2001 Sangoma Technologies Inc.
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 *****************************************************************************/
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 */
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>
37 #include <linux/sdla_chdlc.h> /* CHDLC firmware API definitions */
38 #include <linux/sdla_asy.h> /* CHDLC (async) API definitions */
40 #include <linux/if_wanpipe_common.h> /* Socket Driver common area */
41 #include <linux/if_wanpipe.h>
44 #include <linux/inetdevice.h>
45 #include <asm/uaccess.h>
47 #include <net/syncppp.h>
50 /****** Defines & Macros ****************************************************/
52 #ifdef _DEBUG_
53 #define STATIC
54 #else
55 #define STATIC static
56 #endif
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
63 #define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */
64 #define CHDLC_HDR_LEN 1
66 #define IFF_POINTTOPOINT 0x10
68 #define CHDLC_API 0x01
70 #define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" )
71 #define MAX_BH_BUFF 10
73 #define CRC_LENGTH 2
74 #define PPP_HEADER_LEN 4
76 /******Data Structures*****************************************************/
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
83 typedef struct chdlc_private_area
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 */
110 //FIXME: add driver stats as per frame relay!
112 } chdlc_private_area_t;
114 /* Route Status options */
115 #define NO_ROUTE 0x00
116 #define ADD_ROUTE 0x01
117 #define ROUTE_ADDED 0x02
118 #define REMOVE_ROUTE 0x03
121 /* variable for keeping track of enabling/disabling FT1 monitor status */
122 static int rCount = 0;
124 /* variable for tracking how many interfaces to open for WANPIPE on the
125 two ports */
127 extern void disable_irq(unsigned int);
128 extern void enable_irq(unsigned int);
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);
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);
144 static void if_tx_timeout(struct net_device *dev);
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);
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);
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 *);
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);
188 static int Intr_test_counter;
189 /****** Public Functions ****************************************************/
191 /*============================================================================
192 * Cisco HDLC protocol initialization routine.
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.
200 * Return: 0 o.k.
201 * < 0 failure.
203 int wsppp_init (sdla_t* card, wandev_conf_t* conf)
205 unsigned char port_num;
206 int err;
207 unsigned long max_permitted_baud = 0;
208 SHARED_MEMORY_INFO_STRUCT *flags;
210 union
212 char str[80];
213 } u;
214 volatile CHDLC_MAILBOX_STRUCT* mb;
215 CHDLC_MAILBOX_STRUCT* mb1;
216 unsigned long timeout;
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;
225 /* Find out which Port to use */
226 if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
227 if (card->next){
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;
236 }else{
237 card->u.c.comm_port = conf->comm_port;
239 }else{
240 printk(KERN_ERR "%s: ERROR - Invalid Port Selected!\n",
241 card->wandev.name);
242 return -EINVAL;
246 /* Initialize protocol-specific fields */
247 if(card->hw.type != SDLA_S514){
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;
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;
265 mb = mb1 = card->mbox;
267 if (!card->configured){
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. */
273 timeout = jiffies;
274 while (mb->return_code != 'I') /* Wait 1s for board to initialize */
275 if ((jiffies - timeout) > 1*HZ) break;
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;
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.
292 if (chdlc_read_version(card, u.str))
293 return -EIO;
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);
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;
307 card->wandev.new_if_cnt = 0;
309 /* reset the number of times the 'update()' proc has been called */
310 card->u.c.update_call_count = 0;
312 card->wandev.ttl = conf->ttl;
313 card->wandev.interface = conf->interface;
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;
323 card->wandev.clocking = conf->clocking;
325 port_num = card->u.c.comm_port;
327 /* Setup Port Bps */
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;
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;
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);
353 card->wandev.bps = conf->bps;
354 }else{
355 card->wandev.bps = 0;
358 /* Setup the Port MTU */
359 if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
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;
374 /* Add on a PPP Header */
375 card->wandev.mtu += PPP_HEADER_LEN;
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 !
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);
388 if(card->hw.type != SDLA_S514)
389 enable_irq(card->hw.irq);
391 chdlc_error(card, err, mb1);
392 return -EIO;
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));
405 flags = card->u.c.flags;
407 /* This is for the ports link state */
408 card->wandev.state = WAN_DUALPORT;
409 card->u.c.state = WAN_DISCONNECTED;
412 if (!card->wandev.piggyback){
413 err = intr_test(card);
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;
423 printk(KERN_INFO "%s: Interrupt test passed (%i)\n",
424 card->devname, Intr_test_counter);
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;
434 /* Mask the Timer interrupt */
435 flags->interrupt_info_struct.interrupt_permission &=
436 ~APP_INT_ON_TIMER;
438 printk(KERN_INFO "\n");
440 return 0;
443 /******* WAN Device Driver Entry Points *************************************/
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.
458 static int update(struct wan_device* wandev)
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;
466 /* sanity checks */
467 if((wandev == NULL) || (wandev->private == NULL))
468 return -EFAULT;
470 if(wandev->state == WAN_UNCONFIGURED)
471 return -ENODEV;
473 /* more sanity checks */
474 if(!card->u.c.flags)
475 return -ENODEV;
477 if((dev=card->wandev.dev) == NULL)
478 return -ENODEV;
480 if((chdlc_priv_area=dev->priv) == NULL)
481 return -ENODEV;
483 flags = card->u.c.flags;
485 if(chdlc_priv_area->update_comms_stats){
486 return -EAGAIN;
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;
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;
508 return 0;
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.
521 * Return: 0 o.k.
522 * < 0 failure (channel will not be created)
524 static int new_if(struct wan_device* wandev, struct net_device* pdev,
525 wanif_conf_t* conf)
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;
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;
540 /* allocate and initialize private data */
541 chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
543 if(chdlc_priv_area == NULL)
544 return -ENOMEM;
546 memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
548 chdlc_priv_area->card = card;
550 /* initialize data */
551 strcpy(card->u.c.if_name, conf->name);
553 if(card->wandev.new_if_cnt > 0) {
554 kfree(chdlc_priv_area);
555 return -EEXIST;
558 card->wandev.new_if_cnt++;
560 chdlc_priv_area->TracingEnabled = 0;
562 //We don't need this any more
563 chdlc_priv_area->route_status = NO_ROUTE;
564 chdlc_priv_area->route_removed = 0;
566 printk(KERN_INFO "%s: Firmware running in HDLC STREAMING Mode\n",
567 wandev->name);
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;
582 /* Get Multicast Information */
583 chdlc_priv_area->mc = conf->mc;
586 chdlc_priv_area->if_ptr = pppdev;
588 /* prepare network device data space for registration */
590 strcpy(dev->name,card->u.c.if_name);
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.
598 sppp_attach(pppdev);
599 dev = pppdev->dev;
600 sp = &pppdev->sppp;
602 /* Enable PPP Debugging */
603 // FIXME Fix this up somehow
604 //sp->pp_flags |= PP_DEBUG;
605 sp->pp_flags &= ~PP_CISCO;
607 dev->init = &if_init;
608 dev->priv = chdlc_priv_area;
610 return 0;
616 /*============================================================================
617 * Delete logical channel.
619 static int del_if(struct wan_device* wandev, struct net_device* dev)
621 chdlc_private_area_t *chdlc_priv_area = dev->priv;
622 sdla_t *card = chdlc_priv_area->card;
623 unsigned long smp_lock;
625 /* Detach the PPP layer */
626 printk(KERN_INFO "%s: Detaching SyncPPP Module from %s\n",
627 wandev->name,dev->name);
629 lock_adapter_irq(&wandev->lock,&smp_lock);
631 sppp_detach(dev);
632 chdlc_priv_area->if_ptr=NULL;
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);
639 port_set_state(card, WAN_DISCONNECTED);
641 return 0;
645 /****** Network Device Interface ********************************************/
647 /*============================================================================
648 * Initialize Linux network interface.
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.
654 static int if_init(struct net_device* dev)
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;
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.
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;
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;
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.
688 dev->tx_queue_len = 100;
690 return 0;
694 /*============================================================================
695 * Handle transmit timeout event from netif watchdog
697 static void if_tx_timeout(struct net_device *dev)
699 chdlc_private_area_t* chan = dev->priv;
700 sdla_t *card = chan->card;
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.
708 ++card->wandev.stats.collisions;
710 printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
711 netif_wake_queue (dev);
715 /*============================================================================
716 * Open network interface.
717 * o enable communications and interrupts.
718 * o prevent module from unloading by incrementing use count
720 * Return 0 if O.k. or errno.
722 static int if_open(struct net_device* dev)
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;
729 /* Only one open per interface is allowed */
730 if (netif_running(dev))
731 return -EBUSY;
733 /* Start PPP Layer */
734 if (sppp_open(dev)){
735 return -EIO;
738 do_gettimeofday(&tv);
739 chdlc_priv_area->router_start_time = tv.tv_sec;
741 netif_start_queue(dev);
743 wanpipe_open(card);
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;
750 /*============================================================================
751 * Close network interface.
752 * o if this is the last close, then disable communications and interrupts.
753 * o reset flags.
755 static int if_close(struct net_device* dev)
757 chdlc_private_area_t* chdlc_priv_area = dev->priv;
758 sdla_t* card = chdlc_priv_area->card;
760 /* Stop the PPP Layer */
761 sppp_close(dev);
762 netif_stop_queue(dev);
764 wanpipe_close(card);
766 return 0;
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
777 * Return: 0 complete (socket buffer must be freed)
778 * non-0 packet may be re-transmitted (tbusy must be set)
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.
786 static int if_send(struct sk_buff* skb, struct net_device* dev)
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;
796 netif_stop_queue(dev);
799 if (skb == NULL){
800 /* If we get here, some higher layer thinks we've missed an
801 * tx-done interrupt.
803 printk(KERN_INFO "%s: Received NULL skb buffer! interface %s got kicked!\n",
804 card->devname, dev->name);
806 netif_wake_queue(dev);
807 return 0;
810 if (ntohs(skb->protocol) != htons(PVC_PROT)){
811 /* check the udp packet type */
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;
820 netif_start_queue(dev);
821 return 0;
825 /* Lock the 508 Card: SMP is supported */
826 if(card->hw.type != SDLA_S514){
827 s508_lock(card,&smp_flags);
830 if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)){
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;
839 if (card->wandev.state != WAN_CONNECTED){
840 ++card->wandev.stats.tx_dropped;
841 netif_start_queue(dev);
842 goto if_send_crit_exit;
845 if (chdlc_send(card, skb->data, skb->len)){
846 netif_stop_queue(dev);
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);
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;
863 clear_bit(SEND_CRIT, (void*)&card->wandev.critical);
864 if(card->hw.type != SDLA_S514){
865 s508_unlock(card,&smp_flags);
868 return err;
872 /*============================================================================
873 * Reply to UDP Management system.
874 * Return length of reply.
876 static int reply_udp( unsigned char *data, unsigned int mbox_len )
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;
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;
892 /* fill in UDP reply */
893 c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
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;
902 /* put it on an even boundary */
903 if ( udp_length & 0x0001 ) {
904 udp_length += 1;
905 len += 1;
906 even_bound = 1;
909 temp = (udp_length<<8)|(udp_length>>8);
910 c_udp_pkt->udp_pkt.udp_length = temp;
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;
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;
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);
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;
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;
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));
943 return len;
945 } /* reply_udp */
947 unsigned short calc_checksum (char *data, int len)
949 unsigned short temp;
950 unsigned long sum=0;
951 int i;
953 for( i = 0; i <len; i+=2 ) {
954 memcpy(&temp,&data[i],2);
955 sum += (unsigned long)temp;
958 while (sum >> 16 ) {
959 sum = (sum & 0xffffUL) + (sum >> 16);
962 temp = (unsigned short)sum;
963 temp = ~temp;
965 if( temp == 0 )
966 temp = 0xffff;
968 return temp;
972 /*============================================================================
973 * Get ethernet-style interface statistics.
974 * Return a pointer to struct enet_statistics.
976 static struct net_device_stats* if_stats(struct net_device* dev)
978 sdla_t *my_card;
979 chdlc_private_area_t* chdlc_priv_area;
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;
988 my_card = chdlc_priv_area->card;
989 return &my_card->wandev.stats;
993 /****** Cisco HDLC Firmware Interface Functions *******************************/
995 /*============================================================================
996 * Read firmware code version.
997 * Put code version as ASCII string in str.
999 static int chdlc_read_version (sdla_t* card, char* str)
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;
1008 if(err != COMMAND_OK) {
1009 chdlc_error(card,err,mb);
1011 else if (str) { /* is not null */
1012 len = mb->buffer_length;
1013 memcpy(str, mb->data, len);
1014 str[len] = '\0';
1016 return (err);
1019 /*-----------------------------------------------------------------------------
1020 * Configure CHDLC firmware.
1022 static int chdlc_configure (sdla_t* card, void* data)
1024 int err;
1025 CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
1026 int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);
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;
1033 if (err != COMMAND_OK) chdlc_error (card, err, mailbox);
1035 return err;
1039 /*============================================================================
1040 * Set interrupt mode -- HDLC Version.
1043 static int chdlc_set_intr_mode (sdla_t* card, unsigned mode)
1045 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1046 CHDLC_INT_TRIGGERS_STRUCT* int_data =
1047 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1048 int err;
1050 int_data->CHDLC_interrupt_triggers = mode;
1051 int_data->IRQ = card->hw.irq;
1052 int_data->interrupt_timer = 1;
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;
1063 /*============================================================================
1064 * Enable communications.
1067 static int chdlc_comm_enable (sdla_t* card)
1069 int err;
1070 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
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;
1080 return err;
1083 /*============================================================================
1084 * Disable communications and Drop the Modem lines (DCD and RTS).
1086 static int chdlc_comm_disable (sdla_t* card)
1088 int err;
1089 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
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);
1097 return err;
1100 /*============================================================================
1101 * Read communication error statistics.
1103 static int chdlc_read_comm_err_stats (sdla_t* card)
1105 int err;
1106 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
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;
1117 /*============================================================================
1118 * Read CHDLC operational statistics.
1120 static int chdlc_read_op_stats (sdla_t* card)
1122 int err;
1123 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
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;
1134 /*============================================================================
1135 * Update communications error and general packet statistics.
1137 static int update_comms_stats(sdla_t* card,
1138 chdlc_private_area_t* chdlc_priv_area)
1140 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1141 COMMS_ERROR_STATS_STRUCT* err_stats;
1142 CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;
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;
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);
1173 return 0;
1176 /*============================================================================
1177 * Send packet.
1178 * Return: 0 - o.k.
1179 * 1 - no transmit buffers available
1181 static int chdlc_send (sdla_t* card, void* data, unsigned len)
1183 CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;
1185 if (txbuf->opp_flag)
1186 return 1;
1188 sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);
1190 txbuf->frame_length = len;
1191 txbuf->opp_flag = 1; /* start transmission */
1193 /* Update transmit buffer control fields */
1194 card->u.c.txbuf = ++txbuf;
1196 if ((void*)txbuf > card->u.c.txbuf_last)
1197 card->u.c.txbuf = card->u.c.txbuf_base;
1199 return 0;
1202 /****** Firmware Error Handler **********************************************/
1204 /*============================================================================
1205 * Firmware error handler.
1206 * This routine is called whenever firmware command returns non-zero
1207 * return code.
1209 * Return zero if previous command has to be cancelled.
1211 static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
1213 unsigned cmd = mb->command;
1215 switch (err) {
1217 case CMD_TIMEOUT:
1218 printk(KERN_ERR "%s: command 0x%02X timed out!\n",
1219 card->devname, cmd);
1220 break;
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;
1230 default:
1231 printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
1232 card->devname, cmd, err);
1235 return 0;
1238 /****** Interrupt Handlers **************************************************/
1240 /*============================================================================
1241 * Cisco HDLC interrupt service routine.
1243 STATIC void wsppp_isr (sdla_t* card)
1245 struct net_device* dev;
1246 SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1247 int i;
1248 sdla_t *my_card;
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.
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;
1269 dev = card->wandev.dev;
1270 card->in_isr = 1;
1271 flags = card->u.c.flags;
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;
1281 /* if critical due to peripheral operations
1282 * ie. update() or getstats() then reset the interrupt and
1283 * wait for the board to retrigger.
1285 if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
1286 flags->interrupt_info_struct.
1287 interrupt_type = 0;
1288 goto isr_done;
1292 /* On a 508 Card, if critical due to if_send
1293 * Major Error !!!
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;
1303 switch(flags->interrupt_info_struct.interrupt_type) {
1305 case RX_APP_INT_PEND: /* 0x01: receive interrupt */
1306 rx_intr(card);
1307 break;
1309 case TX_APP_INT_PEND: /* 0x02: transmit interrupt */
1310 flags->interrupt_info_struct.interrupt_permission &=
1311 ~APP_INT_ON_TX_FRAME;
1313 netif_wake_queue(dev);
1314 break;
1316 case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
1317 ++ Intr_test_counter;
1318 break;
1320 case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */
1321 process_chdlc_exception(card);
1322 break;
1324 case GLOBAL_EXCEP_COND_APP_INT_PEND:
1325 process_global_exception(card);
1326 break;
1328 case TIMER_APP_INT_PEND:
1329 timer_intr(card);
1330 break;
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;
1348 isr_done:
1349 card->in_isr = 0;
1350 flags->interrupt_info_struct.interrupt_type = 0;
1353 /*============================================================================
1354 * Receive interrupt handler.
1356 static void rx_intr (sdla_t* card)
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;
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");
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.
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;
1395 dev = card->wandev.dev;
1397 if (!dev){
1398 goto rx_exit;
1401 if (!netif_running(dev)){
1402 goto rx_exit;
1405 chdlc_priv_area = dev->priv;
1407 if (rxbuf->error_flag){
1408 goto rx_exit;
1410 /* Take off two CRC bytes */
1412 if (rxbuf->frame_length < 7 || rxbuf->frame_length > 1506 ){
1413 goto rx_exit;
1416 len = rxbuf->frame_length - CRC_LENGTH;
1418 /* Allocate socket buffer */
1419 skb = dev_alloc_skb(len);
1421 if (skb == NULL) {
1422 if (net_ratelimit()){
1423 printk(KERN_INFO "%s: no socket buffers available!\n",
1424 card->devname);
1426 ++card->wandev.stats.rx_dropped;
1427 goto rx_exit;
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;
1439 buf = skb_put(skb, len);
1440 sdla_peek(&card->hw, addr, buf, len);
1442 skb->protocol = htons(ETH_P_WAN_PPP);
1444 card->wandev.stats.rx_packets ++;
1445 card->wandev.stats.rx_bytes += skb->len;
1446 udp_type = udp_pkt_type( skb, card );
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;
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;
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;
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.
1478 void timer_intr(sdla_t *card)
1480 struct net_device* dev;
1481 chdlc_private_area_t* chdlc_priv_area = NULL;
1482 SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1484 dev = card->wandev.dev;
1485 chdlc_priv_area = dev->priv;
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;
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;
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;
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;
1519 /*------------------------------------------------------------------------------
1520 Miscellaneous Functions
1521 - set_chdlc_config() used to set configuration options on the board
1522 ------------------------------------------------------------------------------*/
1524 static int set_chdlc_config(sdla_t* card)
1527 CHDLC_CONFIGURATION_STRUCT cfg;
1529 memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
1531 if(card->wandev.clocking)
1532 cfg.baud_rate = card->wandev.bps;
1534 cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
1535 INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
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;
1547 cfg.transmit_keepalive_timer = 0;
1548 cfg.receive_keepalive_timer = 0;
1549 cfg.keepalive_error_tolerance = 0;
1550 cfg.SLARP_request_timer = 0;
1552 cfg.IP_address = 0;
1553 cfg.IP_netmask = 0;
1555 return chdlc_configure(card, &cfg);
1558 /*============================================================================
1559 * Process global exception condition
1561 static int process_global_exception(sdla_t *card)
1563 CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
1564 int err;
1566 mbox->buffer_length = 0;
1567 mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
1568 err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
1570 if(err != CMD_TIMEOUT ){
1572 switch(mbox->return_code) {
1574 case EXCEP_MODEM_STATUS_CHANGE:
1576 printk(KERN_INFO "%s: Modem status change\n",
1577 card->devname);
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;
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);
1598 break;
1600 case EXCEP_TRC_DISABLED:
1601 printk(KERN_INFO "%s: Line trace disabled\n",
1602 card->devname);
1603 break;
1605 case EXCEP_IRQ_TIMEOUT:
1606 printk(KERN_INFO "%s: IRQ timeout occurred\n",
1607 card->devname);
1608 break;
1610 default:
1611 printk(KERN_INFO "%s: Global exception %x\n",
1612 card->devname, mbox->return_code);
1613 break;
1616 return 0;
1620 /*============================================================================
1621 * Process chdlc exception condition
1623 static int process_chdlc_exception(sdla_t *card)
1625 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1626 int err;
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) {
1633 switch (err) {
1635 case EXCEP_LINK_ACTIVE:
1636 port_set_state(card, WAN_CONNECTED);
1637 break;
1639 case EXCEP_LINK_INACTIVE_MODEM:
1640 port_set_state(card, WAN_DISCONNECTED);
1641 break;
1643 case EXCEP_LOOPBACK_CONDITION:
1644 printk(KERN_INFO "%s: Loopback Condition Detected.\n",
1645 card->devname);
1646 break;
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;
1659 return 0;
1663 /*=============================================================================
1664 * Store a UDP management packet for later processing.
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 )
1671 int udp_pkt_stored = 0;
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;
1682 if(udp_pkt_src == UDP_PKT_FRM_STACK)
1683 dev_kfree_skb_any(skb);
1684 else
1685 dev_kfree_skb_any(skb);
1687 return(udp_pkt_stored);
1691 /*=============================================================================
1692 * Process UDP management packet.
1695 static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
1696 chdlc_private_area_t* chdlc_priv_area )
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;
1712 chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
1714 if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
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:
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;
1736 if(!udp_mgmt_req_valid) {
1738 /* set length to 0 */
1739 chdlc_udp_pkt->cblock.buffer_length = 0;
1741 /* set return code */
1742 chdlc_udp_pkt->cblock.return_code = 0xCD;
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);
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;
1755 switch(chdlc_udp_pkt->cblock.command) {
1757 case CPIPE_ENABLE_TRACING:
1758 if (!chdlc_priv_area->TracingEnabled) {
1760 /* OPERATE_DATALINE_MONITOR */
1762 mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
1763 mb->command = SET_TRACE_CONFIGURATION;
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 */
1771 /* Configure the Trace based on user inputs */
1772 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |=
1773 chdlc_udp_pkt->data[0];
1775 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
1776 trace_deactivation_timer = 4000;
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;
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;
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;
1801 trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
1802 mb->data) -> ptr_trace_stat_el_cfg_struct;
1804 sdla_peek(&card->hw, trace_status_cfg_addr,
1805 &trace_cfg_struct, sizeof(trace_cfg_struct));
1807 chdlc_priv_area->start_trace_addr = trace_cfg_struct.
1808 base_addr_trace_status_elements;
1810 chdlc_priv_area->number_trace_elements =
1811 trace_cfg_struct.number_trace_status_elements;
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));
1818 chdlc_priv_area->base_addr_trace_buffer =
1819 trace_cfg_struct.base_addr_trace_buffer;
1821 chdlc_priv_area->end_addr_trace_buffer =
1822 trace_cfg_struct.end_addr_trace_buffer;
1824 chdlc_priv_area->curr_trace_addr =
1825 trace_cfg_struct.next_trace_element_to_use;
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);
1834 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1835 mb->buffer_length = 0;
1836 chdlc_priv_area->TracingEnabled = 1;
1837 break;
1840 case CPIPE_DISABLE_TRACING:
1841 if (chdlc_priv_area->TracingEnabled) {
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;
1851 chdlc_priv_area->TracingEnabled = 0;
1852 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1853 mb->buffer_length = 0;
1854 break;
1857 case CPIPE_GET_TRACE_INFO:
1859 if (!chdlc_priv_area->TracingEnabled) {
1860 chdlc_udp_pkt->cblock.return_code = 1;
1861 mb->buffer_length = 0;
1862 break;
1865 chdlc_udp_pkt->trace_info.ismoredata = 0x00;
1866 buffer_length = 0; /* offset of packet already occupied */
1868 for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
1870 trace_pkt_t *trace_pkt = (trace_pkt_t *)
1871 &chdlc_udp_pkt->data[buffer_length];
1873 sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
1874 (unsigned char *)&trace_element_struct,
1875 sizeof(TRACE_STATUS_ELEMENT_STRUCT));
1877 if (trace_element_struct.opp_flag == 0x00) {
1878 break;
1881 /* get pointer to real data */
1882 data_ptr = trace_element_struct.ptr_data_bfr;
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;
1892 if( (chdlc_priv_area->available_buffer_space - buffer_length)
1893 < ( sizeof(trace_pkt_t) + data_length) ) {
1895 /* indicate there are more frames on board & exit */
1896 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
1897 break;
1900 trace_pkt->status = trace_element_struct.trace_type;
1902 trace_pkt->time_stamp =
1903 trace_element_struct.trace_time_stamp;
1905 trace_pkt->real_length =
1906 trace_element_struct.trace_length;
1908 /* see if we can fit the frame into the user buffer */
1909 real_len = trace_pkt->real_length;
1911 if (data_ptr == 0) {
1912 trace_pkt->data_avail = 0x00;
1913 } else {
1914 unsigned tmp = 0;
1916 /* get the data from circular buffer
1917 must check for end of buffer */
1918 trace_pkt->data_avail = 0x01;
1920 if ((data_ptr + real_len) >
1921 chdlc_priv_area->end_addr_trace_buffer + 1){
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;
1929 sdla_peek(&card->hw, data_ptr,
1930 &trace_pkt->data[tmp], real_len - tmp);
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);
1937 /* now move onto the next frame */
1938 chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
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;
1945 if(trace_pkt->data_avail == 0x01) {
1946 buffer_length += real_len - 1;
1949 /* for the header */
1950 buffer_length += sizeof(trace_pkt_t);
1952 } /* For Loop */
1954 if (frames == chdlc_priv_area->number_trace_elements){
1955 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
1957 chdlc_udp_pkt->trace_info.num_frames = frames;
1959 mb->buffer_length = buffer_length;
1960 chdlc_udp_pkt->cblock.buffer_length = buffer_length;
1962 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1964 break;
1967 case CPIPE_FT1_READ_STATUS:
1968 ((unsigned char *)chdlc_udp_pkt->data )[0] =
1969 flags->FT1_info_struct.parallel_port_A_input;
1971 ((unsigned char *)chdlc_udp_pkt->data )[1] =
1972 flags->FT1_info_struct.parallel_port_B_input;
1974 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1975 mb->buffer_length = 2;
1976 break;
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;
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)) {
1992 if( rCount++ != 0 ) {
1993 chdlc_udp_pkt->cblock.
1994 return_code = COMMAND_OK;
1995 mb->buffer_length = 1;
1996 break;
2000 /* Disable FT1 MONITOR STATUS */
2001 if( chdlc_udp_pkt->data[0] == 0) {
2003 if( --rCount != 0) {
2004 chdlc_udp_pkt->cblock.
2005 return_code = COMMAND_OK;
2006 mb->buffer_length = 1;
2007 break;
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);
2019 /* run the command on the board */
2020 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2021 if (err != COMMAND_OK) {
2022 break;
2025 /* copy the result back to our buffer */
2026 memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t));
2028 if (mb->buffer_length) {
2029 memcpy(&chdlc_udp_pkt->data, &mb->data,
2030 mb->buffer_length);
2033 } /* end of switch */
2034 } /* end of else */
2036 /* Fill UDP TTL */
2037 chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
2039 len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
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;
2046 } else {
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 */
2053 buf = skb_put(new_skb, len);
2054 memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
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;
2061 netif_rx(new_skb);
2062 dev->last_rx = jiffies;
2063 } else {
2065 printk(KERN_INFO "%s: no socket buffers available!\n",
2066 card->devname);
2070 chdlc_priv_area->udp_pkt_lgth = 0;
2072 return 0;
2075 /*============================================================================
2076 * Initialize Receive and Transmit Buffers.
2079 static void init_chdlc_tx_rx_buff(sdla_t* card, struct net_device *dev)
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;
2086 mb->buffer_length = 0;
2087 mb->command = READ_CHDLC_CONFIGURATION;
2088 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2090 if(err != COMMAND_OK) {
2091 chdlc_error(card,err,mb);
2092 return;
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));
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);
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);
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);
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));
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));
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);
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));
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;
2158 /*=============================================================================
2159 * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
2160 * _TEST_COUNTER times.
2162 static int intr_test( sdla_t* card)
2164 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2165 int err,i;
2167 Intr_test_counter = 0;
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.
2174 err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
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;
2183 else {
2184 return err;
2187 err = chdlc_set_intr_mode(card, 0);
2189 if (err != CMD_OK)
2190 return err;
2192 return 0;
2195 /*==============================================================================
2196 * Determine what type of UDP call it is. CPIPEAB ?
2198 static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
2200 chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
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;
2208 else return UDP_INVALID_TYPE;
2211 /*============================================================================
2212 * Set PORT state.
2214 static void port_set_state (sdla_t *card, int state)
2216 struct net_device *dev = card->wandev.dev;
2217 chdlc_private_area_t *chdlc_priv_area = dev->priv;
2219 if (card->u.c.state != state)
2221 switch (state)
2223 case WAN_CONNECTED:
2224 printk (KERN_INFO "%s: HDLC link connected!\n",
2225 card->devname);
2226 break;
2228 case WAN_CONNECTING:
2229 printk (KERN_INFO "%s: HDLC link connecting...\n",
2230 card->devname);
2231 break;
2233 case WAN_DISCONNECTED:
2234 printk (KERN_INFO "%s: HDLC link disconnected!\n",
2235 card->devname);
2236 break;
2239 card->wandev.state = card->u.c.state = state;
2240 chdlc_priv_area->common.state = state;
2244 void s508_lock (sdla_t *card, unsigned long *smp_flags)
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);
2254 void s508_unlock (sdla_t *card, unsigned long *smp_flags)
2256 if (card->next){
2257 spin_unlock(&card->next->wandev.lock);
2259 spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
2264 /*===========================================================================
2265 * config_chdlc
2267 * Configure the chdlc protocol and enable communications.
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.
2274 * If the communications are not enabled, proceed to configure
2275 * the card and enable communications.
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.
2285 static int config_chdlc (sdla_t *card)
2287 struct net_device *dev = card->wandev.dev;
2288 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
2290 if (card->u.c.comm_enabled){
2291 chdlc_comm_disable(card);
2292 port_set_state(card, WAN_DISCONNECTED);
2295 if (set_chdlc_config(card)) {
2296 printk(KERN_INFO "%s: CHDLC Configuration Failed!\n",
2297 card->devname);
2298 return 0;
2300 init_chdlc_tx_rx_buff(card, dev);
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;
2313 /* Mask the Transmit and Timer interrupt */
2314 flags->interrupt_info_struct.interrupt_permission &=
2315 ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
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;
2327 /* Initialize Rx/Tx buffer control fields */
2328 port_set_state(card, WAN_CONNECTING);
2329 return 0;
2333 static void send_ppp_term_request(struct net_device *dev)
2335 struct sk_buff *new_skb;
2336 unsigned char *buf;
2338 if ((new_skb = dev_alloc_skb(8)) != NULL) {
2339 /* copy data into new_skb */
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);
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;
2349 netif_rx(new_skb);
2350 dev->last_rx = jiffies;
2355 MODULE_LICENSE("GPL");
2357 /****** End ****************************************************************/