[TG3]: Set minimal hw interrupt mitigation.
[linux-2.6/verdex.git] / drivers / net / wan / sdla_chdlc.c
blob496d29237e92750bb0ad090d6e7d3b12c7a14e4b
1 /*****************************************************************************
2 * sdla_chdlc.c WANPIPE(tm) Multiprotocol WAN Link Driver. Cisco HDLC module.
4 * Authors: Nenad Corbic <ncorbic@sangoma.com>
5 * Gideon Hack
7 * Copyright: (c) 1995-2001 Sangoma Technologies Inc.
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version
12 * 2 of the License, or (at your option) any later version.
13 * ============================================================================
14 * Feb 28, 2001 Nenad Corbic Updated if_tx_timeout() routine for
15 * 2.4.X kernels.
16 * Jan 25, 2001 Nenad Corbic Added a TTY Sync serial driver over the
17 * HDLC streaming protocol
18 * Added a TTY Async serial driver over the
19 * Async protocol.
20 * Dec 15, 2000 Nenad Corbic Updated for 2.4.X Kernel support
21 * Nov 13, 2000 Nenad Corbic Added true interface type encoding option.
22 * Tcpdump doesn't support CHDLC inteface
23 * types, to fix this "true type" option will set
24 * the interface type to RAW IP mode.
25 * Nov 07, 2000 Nenad Corbic Added security features for UDP debugging:
26 * Deny all and specify allowed requests.
27 * Jun 20, 2000 Nenad Corbic Fixed the API IP ERROR bug. Caused by the
28 * latest update.
29 * May 09, 2000 Nenad Corbic Option to bring down an interface
30 * upon disconnect.
31 * Mar 23, 2000 Nenad Corbic Improved task queue, bh handling.
32 * Mar 16, 2000 Nenad Corbic Fixed the SLARP Dynamic IP addressing.
33 * Mar 06, 2000 Nenad Corbic Bug Fix: corrupted mbox recovery.
34 * Feb 10, 2000 Gideon Hack Added ASYNC support.
35 * Feb 09, 2000 Nenad Corbic Fixed two shutdown bugs in update() and
36 * if_stats() functions.
37 * Jan 24, 2000 Nenad Corbic Fixed a startup wanpipe state racing,
38 * condition between if_open and isr.
39 * Jan 10, 2000 Nenad Corbic Added new socket API support.
40 * Dev 15, 1999 Nenad Corbic Fixed up header files for 2.0.X kernels
41 * Nov 20, 1999 Nenad Corbic Fixed zero length API bug.
42 * Sep 30, 1999 Nenad Corbic Fixed dynamic IP and route setup.
43 * Sep 23, 1999 Nenad Corbic Added SMP support, fixed tracing
44 * Sep 13, 1999 Nenad Corbic Split up Port 0 and 1 into separate devices.
45 * Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
46 * Oct 30, 1998 Jaspreet Singh Added Support for CHDLC API (HDLC STREAMING).
47 * Oct 28, 1998 Jaspreet Singh Added Support for Dual Port CHDLC.
48 * Aug 07, 1998 David Fong Initial version.
49 *****************************************************************************/
51 #include <linux/module.h>
52 #include <linux/kernel.h> /* printk(), and other useful stuff */
53 #include <linux/stddef.h> /* offsetof(), etc. */
54 #include <linux/errno.h> /* return codes */
55 #include <linux/string.h> /* inline memset(), etc. */
56 #include <linux/slab.h> /* kmalloc(), kfree() */
57 #include <linux/wanrouter.h> /* WAN router definitions */
58 #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
59 #include <linux/if_arp.h> /* ARPHRD_* defines */
62 #include <asm/uaccess.h>
63 #include <linux/inetdevice.h>
64 #include <linux/netdevice.h>
66 #include <linux/in.h> /* sockaddr_in */
67 #include <linux/inet.h>
68 #include <linux/if.h>
69 #include <asm/byteorder.h> /* htons(), etc. */
70 #include <linux/sdlapci.h>
71 #include <asm/io.h>
73 #include <linux/sdla_chdlc.h> /* CHDLC firmware API definitions */
74 #include <linux/sdla_asy.h> /* CHDLC (async) API definitions */
76 #include <linux/if_wanpipe_common.h> /* Socket Driver common area */
77 #include <linux/if_wanpipe.h>
79 /* TTY Includes */
80 #include <linux/tty.h>
81 #include <linux/tty_flip.h>
82 #include <linux/serial.h>
85 /****** Defines & Macros ****************************************************/
87 /* reasons for enabling the timer interrupt on the adapter */
88 #define TMR_INT_ENABLED_UDP 0x01
89 #define TMR_INT_ENABLED_UPDATE 0x02
90 #define TMR_INT_ENABLED_CONFIG 0x10
92 #define MAX_IP_ERRORS 10
94 #define TTY_CHDLC_MAX_MTU 2000
95 #define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */
96 #define CHDLC_HDR_LEN 1
98 #define CHDLC_API 0x01
100 #define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" )
101 #define MAX_BH_BUFF 10
103 //#define PRINT_DEBUG
104 #ifdef PRINT_DEBUG
105 #define dbg_printk(format, a...) printk(format, ## a)
106 #else
107 #define dbg_printk(format, a...)
108 #endif
110 /******Data Structures*****************************************************/
112 /* This structure is placed in the private data area of the device structure.
113 * The card structure used to occupy the private area but now the following
114 * structure will incorporate the card structure along with CHDLC specific data
117 typedef struct chdlc_private_area
119 wanpipe_common_t common;
120 sdla_t *card;
121 int TracingEnabled; /* For enabling Tracing */
122 unsigned long curr_trace_addr; /* Used for Tracing */
123 unsigned long start_trace_addr;
124 unsigned long end_trace_addr;
125 unsigned long base_addr_trace_buffer;
126 unsigned long end_addr_trace_buffer;
127 unsigned short number_trace_elements;
128 unsigned available_buffer_space;
129 unsigned long router_start_time;
130 unsigned char route_status;
131 unsigned char route_removed;
132 unsigned long tick_counter; /* For 5s timeout counter */
133 unsigned long router_up_time;
134 u32 IP_address; /* IP addressing */
135 u32 IP_netmask;
136 u32 ip_local;
137 u32 ip_remote;
138 u32 ip_local_tmp;
139 u32 ip_remote_tmp;
140 u8 ip_error;
141 u8 config_chdlc;
142 u8 config_chdlc_timeout;
143 unsigned char mc; /* Mulitcast support on/off */
144 unsigned short udp_pkt_lgth; /* udp packet processing */
145 char udp_pkt_src;
146 char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
147 unsigned short timer_int_enabled;
148 char update_comms_stats; /* updating comms stats */
150 bh_data_t *bh_head; /* Circular buffer for chdlc_bh */
151 unsigned long tq_working;
152 volatile int bh_write;
153 volatile int bh_read;
154 atomic_t bh_buff_used;
156 unsigned char interface_down;
158 /* Polling work queue entry. Each interface
159 * has its own work queue entry, which is used
160 * to defer events from the interrupt */
161 struct work_struct poll_work;
162 struct timer_list poll_delay_timer;
164 u8 gateway;
165 u8 true_if_encoding;
166 //FIXME: add driver stats as per frame relay!
168 } chdlc_private_area_t;
170 /* Route Status options */
171 #define NO_ROUTE 0x00
172 #define ADD_ROUTE 0x01
173 #define ROUTE_ADDED 0x02
174 #define REMOVE_ROUTE 0x03
177 /* variable for keeping track of enabling/disabling FT1 monitor status */
178 static int rCount = 0;
180 /* variable for tracking how many interfaces to open for WANPIPE on the
181 two ports */
183 extern void disable_irq(unsigned int);
184 extern void enable_irq(unsigned int);
186 /****** Function Prototypes *************************************************/
187 /* WAN link driver entry points. These are called by the WAN router module. */
188 static int update(struct wan_device* wandev);
189 static int new_if(struct wan_device* wandev, struct net_device* dev,
190 wanif_conf_t* conf);
192 /* Network device interface */
193 static int if_init(struct net_device* dev);
194 static int if_open(struct net_device* dev);
195 static int if_close(struct net_device* dev);
196 static int if_header(struct sk_buff* skb, struct net_device* dev,
197 unsigned short type, void* daddr, void* saddr,
198 unsigned len);
200 static int if_rebuild_hdr (struct sk_buff *skb);
201 static struct net_device_stats* if_stats(struct net_device* dev);
203 static int if_send(struct sk_buff* skb, struct net_device* dev);
205 /* CHDLC Firmware interface functions */
206 static int chdlc_configure (sdla_t* card, void* data);
207 static int chdlc_comm_enable (sdla_t* card);
208 static int chdlc_read_version (sdla_t* card, char* str);
209 static int chdlc_set_intr_mode (sdla_t* card, unsigned mode);
210 static int chdlc_send (sdla_t* card, void* data, unsigned len);
211 static int chdlc_read_comm_err_stats (sdla_t* card);
212 static int chdlc_read_op_stats (sdla_t* card);
213 static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
216 static int chdlc_disable_comm_shutdown (sdla_t *card);
217 static void if_tx_timeout(struct net_device *dev);
219 /* Miscellaneous CHDLC Functions */
220 static int set_chdlc_config (sdla_t* card);
221 static void init_chdlc_tx_rx_buff( sdla_t* card);
222 static int process_chdlc_exception(sdla_t *card);
223 static int process_global_exception(sdla_t *card);
224 static int update_comms_stats(sdla_t* card,
225 chdlc_private_area_t* chdlc_priv_area);
226 static int configure_ip (sdla_t* card);
227 static int unconfigure_ip (sdla_t* card);
228 static void process_route(sdla_t *card);
229 static void port_set_state (sdla_t *card, int);
230 static int config_chdlc (sdla_t *card);
231 static void disable_comm (sdla_t *card);
233 static void trigger_chdlc_poll(struct net_device *dev);
234 static void chdlc_poll(struct net_device *dev);
235 static void chdlc_poll_delay (unsigned long dev_ptr);
238 /* Miscellaneous asynchronous interface Functions */
239 static int set_asy_config (sdla_t* card);
240 static int asy_comm_enable (sdla_t* card);
242 /* Interrupt handlers */
243 static void wpc_isr (sdla_t* card);
244 static void rx_intr (sdla_t* card);
245 static void timer_intr(sdla_t *);
247 /* Bottom half handlers */
248 static void chdlc_work(struct net_device *dev);
249 static int chdlc_work_cleanup(struct net_device *dev);
250 static int bh_enqueue(struct net_device *dev, struct sk_buff *skb);
252 /* Miscellaneous functions */
253 static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev,
254 struct sk_buff *skb);
255 static int reply_udp( unsigned char *data, unsigned int mbox_len );
256 static int intr_test( sdla_t* card);
257 static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
258 static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
259 struct sk_buff *skb, struct net_device* dev,
260 chdlc_private_area_t* chdlc_priv_area);
261 static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
262 chdlc_private_area_t* chdlc_priv_area);
263 static unsigned short calc_checksum (char *, int);
264 static void s508_lock (sdla_t *card, unsigned long *smp_flags);
265 static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
268 static int Intr_test_counter;
270 /* TTY Global Definitions */
272 #define NR_PORTS 4
273 #define WAN_TTY_MAJOR 226
274 #define WAN_TTY_MINOR 0
276 #define WAN_CARD(port) (tty_card_map[port])
277 #define MIN_PORT 0
278 #define MAX_PORT NR_PORTS-1
280 #define CRC_LENGTH 2
282 static int wanpipe_tty_init(sdla_t *card);
283 static void wanpipe_tty_receive(sdla_t *, unsigned, unsigned int);
284 static void wanpipe_tty_trigger_poll(sdla_t *card);
286 static struct tty_driver serial_driver;
287 static int tty_init_cnt=0;
289 static struct serial_state rs_table[NR_PORTS];
291 static char tty_driver_mode=WANOPT_TTY_SYNC;
293 static char *opt_decode[] = {"NONE","CRTSCTS","XONXOFF-RX",
294 "CRTSCTS XONXOFF-RX","XONXOFF-TX",
295 "CRTSCTS XONXOFF-TX","CRTSCTS XONXOFF"};
296 static char *p_decode[] = {"NONE","ODD","EVEN"};
298 static void* tty_card_map[NR_PORTS] = {NULL,NULL,NULL,NULL};
301 /****** Public Functions ****************************************************/
303 /*============================================================================
304 * Cisco HDLC protocol initialization routine.
306 * This routine is called by the main WANPIPE module during setup. At this
307 * point adapter is completely initialized and firmware is running.
308 * o read firmware version (to make sure it's alive)
309 * o configure adapter
310 * o initialize protocol-specific fields of the adapter data space.
312 * Return: 0 o.k.
313 * < 0 failure.
315 int wpc_init (sdla_t* card, wandev_conf_t* conf)
317 unsigned char port_num;
318 int err;
319 unsigned long max_permitted_baud = 0;
320 SHARED_MEMORY_INFO_STRUCT *flags;
322 union
324 char str[80];
325 } u;
326 volatile CHDLC_MAILBOX_STRUCT* mb;
327 CHDLC_MAILBOX_STRUCT* mb1;
328 unsigned long timeout;
330 /* Verify configuration ID */
331 if (conf->config_id != WANCONFIG_CHDLC) {
332 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
333 card->devname, conf->config_id);
334 return -EINVAL;
337 /* Find out which Port to use */
338 if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
339 if (card->next){
341 if (conf->comm_port != card->next->u.c.comm_port){
342 card->u.c.comm_port = conf->comm_port;
343 }else{
344 printk(KERN_INFO "%s: ERROR - %s port used!\n",
345 card->wandev.name, PORT(conf->comm_port));
346 return -EINVAL;
348 }else{
349 card->u.c.comm_port = conf->comm_port;
351 }else{
352 printk(KERN_INFO "%s: ERROR - Invalid Port Selected!\n",
353 card->wandev.name);
354 return -EINVAL;
358 /* Initialize protocol-specific fields */
359 if(card->hw.type != SDLA_S514){
361 if (card->u.c.comm_port == WANOPT_PRI){
362 card->mbox = (void *) card->hw.dpmbase;
363 }else{
364 card->mbox = (void *) card->hw.dpmbase +
365 SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
367 }else{
368 /* for a S514 adapter, set a pointer to the actual mailbox in the */
369 /* allocated virtual memory area */
370 if (card->u.c.comm_port == WANOPT_PRI){
371 card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
372 }else{
373 card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
377 mb = mb1 = card->mbox;
379 if (!card->configured){
381 /* The board will place an 'I' in the return code to indicate that it is
382 ready to accept commands. We expect this to be completed in less
383 than 1 second. */
385 timeout = jiffies;
386 while (mb->return_code != 'I') /* Wait 1s for board to initialize */
387 if ((jiffies - timeout) > 1*HZ) break;
389 if (mb->return_code != 'I') {
390 printk(KERN_INFO
391 "%s: Initialization not completed by adapter\n",
392 card->devname);
393 printk(KERN_INFO "Please contact Sangoma representative.\n");
394 return -EIO;
398 /* Read firmware version. Note that when adapter initializes, it
399 * clears the mailbox, so it may appear that the first command was
400 * executed successfully when in fact it was merely erased. To work
401 * around this, we execute the first command twice.
404 if (chdlc_read_version(card, u.str))
405 return -EIO;
407 printk(KERN_INFO "%s: Running Cisco HDLC firmware v%s\n",
408 card->devname, u.str);
410 card->isr = &wpc_isr;
411 card->poll = NULL;
412 card->exec = NULL;
413 card->wandev.update = &update;
414 card->wandev.new_if = &new_if;
415 card->wandev.del_if = NULL;
416 card->wandev.udp_port = conf->udp_port;
417 card->disable_comm = &disable_comm;
418 card->wandev.new_if_cnt = 0;
420 /* reset the number of times the 'update()' proc has been called */
421 card->u.c.update_call_count = 0;
423 card->wandev.ttl = conf->ttl;
424 card->wandev.interface = conf->interface;
426 if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
427 card->hw.type != SDLA_S514){
428 printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n",
429 card->devname, PORT(card->u.c.comm_port));
430 return -EIO;
433 card->wandev.clocking = conf->clocking;
435 port_num = card->u.c.comm_port;
437 /* in API mode, we can configure for "receive only" buffering */
438 if(card->hw.type == SDLA_S514) {
439 card->u.c.receive_only = conf->receive_only;
440 if(conf->receive_only) {
441 printk(KERN_INFO
442 "%s: Configured for 'receive only' mode\n",
443 card->devname);
447 /* Setup Port Bps */
449 if(card->wandev.clocking) {
450 if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
451 /* For Primary Port 0 */
452 max_permitted_baud =
453 (card->hw.type == SDLA_S514) ?
454 PRI_MAX_BAUD_RATE_S514 :
455 PRI_MAX_BAUD_RATE_S508;
457 }else if(port_num == WANOPT_SEC) {
458 /* For Secondary Port 1 */
459 max_permitted_baud =
460 (card->hw.type == SDLA_S514) ?
461 SEC_MAX_BAUD_RATE_S514 :
462 SEC_MAX_BAUD_RATE_S508;
465 if(conf->bps > max_permitted_baud) {
466 conf->bps = max_permitted_baud;
467 printk(KERN_INFO "%s: Baud too high!\n",
468 card->wandev.name);
469 printk(KERN_INFO "%s: Baud rate set to %lu bps\n",
470 card->wandev.name, max_permitted_baud);
472 card->wandev.bps = conf->bps;
473 }else{
474 card->wandev.bps = 0;
477 /* Setup the Port MTU */
478 if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
480 /* For Primary Port 0 */
481 card->wandev.mtu =
482 (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
483 min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
484 CHDLC_DFLT_DATA_LEN;
485 } else if(port_num == WANOPT_SEC) {
486 /* For Secondary Port 1 */
487 card->wandev.mtu =
488 (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
489 min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
490 CHDLC_DFLT_DATA_LEN;
493 /* Set up the interrupt status area */
494 /* Read the CHDLC Configuration and obtain:
495 * Ptr to shared memory infor struct
496 * Use this pointer to calculate the value of card->u.c.flags !
498 mb1->buffer_length = 0;
499 mb1->command = READ_CHDLC_CONFIGURATION;
500 err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
501 if(err != COMMAND_OK) {
502 if(card->hw.type != SDLA_S514)
503 enable_irq(card->hw.irq);
505 chdlc_error(card, err, mb1);
506 return -EIO;
509 if(card->hw.type == SDLA_S514){
510 card->u.c.flags = (void *)(card->hw.dpmbase +
511 (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
512 ptr_shared_mem_info_struct));
513 }else{
514 card->u.c.flags = (void *)(card->hw.dpmbase +
515 (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
516 ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
519 flags = card->u.c.flags;
521 /* This is for the ports link state */
522 card->wandev.state = WAN_DUALPORT;
523 card->u.c.state = WAN_DISCONNECTED;
526 if (!card->wandev.piggyback){
527 int err;
529 /* Perform interrupt testing */
530 err = intr_test(card);
532 if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
533 printk(KERN_INFO "%s: Interrupt test failed (%i)\n",
534 card->devname, Intr_test_counter);
535 printk(KERN_INFO "%s: Please choose another interrupt\n",
536 card->devname);
537 return -EIO;
540 printk(KERN_INFO "%s: Interrupt test passed (%i)\n",
541 card->devname, Intr_test_counter);
542 card->configured = 1;
545 if ((card->tty_opt=conf->tty) == WANOPT_YES){
546 int err;
547 card->tty_minor = conf->tty_minor;
549 /* On ASYNC connections internal clocking
550 * is mandatory */
551 if ((card->u.c.async_mode = conf->tty_mode)){
552 card->wandev.clocking = 1;
554 err=wanpipe_tty_init(card);
555 if (err){
556 return err;
558 }else{
561 if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
562 printk (KERN_INFO "%s: "
563 "Failed to set interrupt triggers!\n",
564 card->devname);
565 return -EIO;
568 /* Mask the Timer interrupt */
569 flags->interrupt_info_struct.interrupt_permission &=
570 ~APP_INT_ON_TIMER;
573 /* If we are using CHDLC in backup mode, this flag will
574 * indicate not to look for IP addresses in config_chdlc()*/
575 card->u.c.backup = conf->backup;
577 printk(KERN_INFO "\n");
579 return 0;
582 /******* WAN Device Driver Entry Points *************************************/
584 /*============================================================================
585 * Update device status & statistics
586 * This procedure is called when updating the PROC file system and returns
587 * various communications statistics. These statistics are accumulated from 3
588 * different locations:
589 * 1) The 'if_stats' recorded for the device.
590 * 2) Communication error statistics on the adapter.
591 * 3) CHDLC operational statistics on the adapter.
592 * The board level statistics are read during a timer interrupt. Note that we
593 * read the error and operational statistics during consecitive timer ticks so
594 * as to minimize the time that we are inside the interrupt handler.
597 static int update(struct wan_device* wandev)
599 sdla_t* card = wandev->private;
600 struct net_device* dev;
601 volatile chdlc_private_area_t* chdlc_priv_area;
602 SHARED_MEMORY_INFO_STRUCT *flags;
603 unsigned long timeout;
605 /* sanity checks */
606 if((wandev == NULL) || (wandev->private == NULL))
607 return -EFAULT;
609 if(wandev->state == WAN_UNCONFIGURED)
610 return -ENODEV;
612 /* more sanity checks */
613 if(!card->u.c.flags)
614 return -ENODEV;
616 if(test_bit(PERI_CRIT, (void*)&card->wandev.critical))
617 return -EAGAIN;
619 if((dev=card->wandev.dev) == NULL)
620 return -ENODEV;
622 if((chdlc_priv_area=dev->priv) == NULL)
623 return -ENODEV;
625 flags = card->u.c.flags;
626 if(chdlc_priv_area->update_comms_stats){
627 return -EAGAIN;
630 /* we will need 2 timer interrupts to complete the */
631 /* reading of the statistics */
632 chdlc_priv_area->update_comms_stats = 2;
633 flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
634 chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
636 /* wait a maximum of 1 second for the statistics to be updated */
637 timeout = jiffies;
638 for(;;) {
639 if(chdlc_priv_area->update_comms_stats == 0)
640 break;
641 if ((jiffies - timeout) > (1 * HZ)){
642 chdlc_priv_area->update_comms_stats = 0;
643 chdlc_priv_area->timer_int_enabled &=
644 ~TMR_INT_ENABLED_UPDATE;
645 return -EAGAIN;
649 return 0;
653 /*============================================================================
654 * Create new logical channel.
655 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
656 * handled.
657 * o parse media- and hardware-specific configuration
658 * o make sure that a new channel can be created
659 * o allocate resources, if necessary
660 * o prepare network device structure for registaration.
662 * Return: 0 o.k.
663 * < 0 failure (channel will not be created)
665 static int new_if(struct wan_device* wandev, struct net_device* dev,
666 wanif_conf_t* conf)
668 sdla_t* card = wandev->private;
669 chdlc_private_area_t* chdlc_priv_area;
672 printk(KERN_INFO "%s: Configuring Interface: %s\n",
673 card->devname, conf->name);
675 if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
676 printk(KERN_INFO "%s: Invalid interface name!\n",
677 card->devname);
678 return -EINVAL;
681 /* allocate and initialize private data */
682 chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
684 if(chdlc_priv_area == NULL)
685 return -ENOMEM;
687 memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
689 chdlc_priv_area->card = card;
690 chdlc_priv_area->common.sk = NULL;
691 chdlc_priv_area->common.func = NULL;
693 /* initialize data */
694 strcpy(card->u.c.if_name, conf->name);
696 if(card->wandev.new_if_cnt > 0) {
697 kfree(chdlc_priv_area);
698 return -EEXIST;
701 card->wandev.new_if_cnt++;
703 chdlc_priv_area->TracingEnabled = 0;
704 chdlc_priv_area->route_status = NO_ROUTE;
705 chdlc_priv_area->route_removed = 0;
707 card->u.c.async_mode = conf->async_mode;
709 /* setup for asynchronous mode */
710 if(conf->async_mode) {
711 printk(KERN_INFO "%s: Configuring for asynchronous mode\n",
712 wandev->name);
714 if(card->u.c.comm_port == WANOPT_PRI) {
715 printk(KERN_INFO
716 "%s:Asynchronous mode on secondary port only\n",
717 wandev->name);
718 kfree(chdlc_priv_area);
719 return -EINVAL;
722 if(strcmp(conf->usedby, "WANPIPE") == 0) {
723 printk(KERN_INFO
724 "%s: Running in WANIPE Async Mode\n", wandev->name);
725 card->u.c.usedby = WANPIPE;
726 }else{
727 card->u.c.usedby = API;
730 if(!card->wandev.clocking) {
731 printk(KERN_INFO
732 "%s: Asynch. clocking must be 'Internal'\n",
733 wandev->name);
734 kfree(chdlc_priv_area);
735 return -EINVAL;
738 if((card->wandev.bps < MIN_ASY_BAUD_RATE) ||
739 (card->wandev.bps > MAX_ASY_BAUD_RATE)) {
740 printk(KERN_INFO "%s: Selected baud rate is invalid.\n",
741 wandev->name);
742 printk(KERN_INFO "Must be between %u and %u bps.\n",
743 MIN_ASY_BAUD_RATE, MAX_ASY_BAUD_RATE);
744 kfree(chdlc_priv_area);
745 return -EINVAL;
748 card->u.c.api_options = 0;
749 if (conf->asy_data_trans == WANOPT_YES) {
750 card->u.c.api_options |= ASY_RX_DATA_TRANSPARENT;
753 card->u.c.protocol_options = 0;
754 if (conf->rts_hs_for_receive == WANOPT_YES) {
755 card->u.c.protocol_options |= ASY_RTS_HS_FOR_RX;
757 if (conf->xon_xoff_hs_for_receive == WANOPT_YES) {
758 card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_RX;
760 if (conf->xon_xoff_hs_for_transmit == WANOPT_YES) {
761 card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_TX;
763 if (conf->dcd_hs_for_transmit == WANOPT_YES) {
764 card->u.c.protocol_options |= ASY_DCD_HS_FOR_TX;
766 if (conf->cts_hs_for_transmit == WANOPT_YES) {
767 card->u.c.protocol_options |= ASY_CTS_HS_FOR_TX;
770 card->u.c.tx_bits_per_char = conf->tx_bits_per_char;
771 card->u.c.rx_bits_per_char = conf->rx_bits_per_char;
772 card->u.c.stop_bits = conf->stop_bits;
773 card->u.c.parity = conf->parity;
774 card->u.c.break_timer = conf->break_timer;
775 card->u.c.inter_char_timer = conf->inter_char_timer;
776 card->u.c.rx_complete_length = conf->rx_complete_length;
777 card->u.c.xon_char = conf->xon_char;
779 } else { /* setup for synchronous mode */
781 card->u.c.protocol_options = 0;
782 if (conf->ignore_dcd == WANOPT_YES){
783 card->u.c.protocol_options |= IGNORE_DCD_FOR_LINK_STAT;
785 if (conf->ignore_cts == WANOPT_YES){
786 card->u.c.protocol_options |= IGNORE_CTS_FOR_LINK_STAT;
789 if (conf->ignore_keepalive == WANOPT_YES) {
790 card->u.c.protocol_options |=
791 IGNORE_KPALV_FOR_LINK_STAT;
792 card->u.c.kpalv_tx = MIN_Tx_KPALV_TIMER;
793 card->u.c.kpalv_rx = MIN_Rx_KPALV_TIMER;
794 card->u.c.kpalv_err = MIN_KPALV_ERR_TOL;
796 } else { /* Do not ignore keepalives */
797 card->u.c.kpalv_tx =
798 ((conf->keepalive_tx_tmr - MIN_Tx_KPALV_TIMER)
799 >= 0) ?
800 min_t(unsigned int, conf->keepalive_tx_tmr,MAX_Tx_KPALV_TIMER) :
801 DEFAULT_Tx_KPALV_TIMER;
803 card->u.c.kpalv_rx =
804 ((conf->keepalive_rx_tmr - MIN_Rx_KPALV_TIMER)
805 >= 0) ?
806 min_t(unsigned int, conf->keepalive_rx_tmr,MAX_Rx_KPALV_TIMER) :
807 DEFAULT_Rx_KPALV_TIMER;
809 card->u.c.kpalv_err =
810 ((conf->keepalive_err_margin-MIN_KPALV_ERR_TOL)
811 >= 0) ?
812 min_t(unsigned int, conf->keepalive_err_margin,
813 MAX_KPALV_ERR_TOL) :
814 DEFAULT_KPALV_ERR_TOL;
817 /* Setup slarp timer to control delay between slarps */
818 card->u.c.slarp_timer =
819 ((conf->slarp_timer - MIN_SLARP_REQ_TIMER) >= 0) ?
820 min_t(unsigned int, conf->slarp_timer, MAX_SLARP_REQ_TIMER) :
821 DEFAULT_SLARP_REQ_TIMER;
823 if (conf->hdlc_streaming == WANOPT_YES) {
824 printk(KERN_INFO "%s: Enabling HDLC STREAMING Mode\n",
825 wandev->name);
826 card->u.c.protocol_options = HDLC_STREAMING_MODE;
829 if ((chdlc_priv_area->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){
830 printk(KERN_INFO
831 "%s: Enabling, true interface type encoding.\n",
832 card->devname);
835 /* Setup wanpipe as a router (WANPIPE) or as an API */
836 if( strcmp(conf->usedby, "WANPIPE") == 0) {
838 printk(KERN_INFO "%s: Running in WANPIPE mode!\n",
839 wandev->name);
840 card->u.c.usedby = WANPIPE;
842 /* Option to bring down the interface when
843 * the link goes down */
844 if (conf->if_down){
845 set_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down);
846 printk(KERN_INFO
847 "%s: Dynamic interface configuration enabled\n",
848 card->devname);
851 } else if( strcmp(conf->usedby, "API") == 0) {
852 card->u.c.usedby = API;
853 printk(KERN_INFO "%s: Running in API mode !\n",
854 wandev->name);
858 /* Tells us that if this interface is a
859 * gateway or not */
860 if ((chdlc_priv_area->gateway = conf->gateway) == WANOPT_YES){
861 printk(KERN_INFO "%s: Interface %s is set as a gateway.\n",
862 card->devname,card->u.c.if_name);
865 /* Get Multicast Information */
866 chdlc_priv_area->mc = conf->mc;
868 /* prepare network device data space for registration */
869 strcpy(dev->name,card->u.c.if_name);
871 dev->init = &if_init;
872 dev->priv = chdlc_priv_area;
874 /* Initialize the polling work routine */
875 INIT_WORK(&chdlc_priv_area->poll_work, (void*)(void*)chdlc_poll, dev);
877 /* Initialize the polling delay timer */
878 init_timer(&chdlc_priv_area->poll_delay_timer);
879 chdlc_priv_area->poll_delay_timer.data = (unsigned long)dev;
880 chdlc_priv_area->poll_delay_timer.function = chdlc_poll_delay;
882 printk(KERN_INFO "\n");
884 return 0;
888 /****** Network Device Interface ********************************************/
890 /*============================================================================
891 * Initialize Linux network interface.
893 * This routine is called only once for each interface, during Linux network
894 * interface registration. Returning anything but zero will fail interface
895 * registration.
897 static int if_init(struct net_device* dev)
899 chdlc_private_area_t* chdlc_priv_area = dev->priv;
900 sdla_t* card = chdlc_priv_area->card;
901 struct wan_device* wandev = &card->wandev;
903 /* Initialize device driver entry points */
904 dev->open = &if_open;
905 dev->stop = &if_close;
906 dev->hard_header = &if_header;
907 dev->rebuild_header = &if_rebuild_hdr;
908 dev->hard_start_xmit = &if_send;
909 dev->get_stats = &if_stats;
910 dev->tx_timeout = &if_tx_timeout;
911 dev->watchdog_timeo = TX_TIMEOUT;
913 /* Initialize media-specific parameters */
914 dev->flags |= IFF_POINTOPOINT;
915 dev->flags |= IFF_NOARP;
917 /* Enable Mulitcasting if user selected */
918 if (chdlc_priv_area->mc == WANOPT_YES){
919 dev->flags |= IFF_MULTICAST;
922 if (chdlc_priv_area->true_if_encoding){
923 dev->type = ARPHRD_HDLC; /* This breaks the tcpdump */
924 }else{
925 dev->type = ARPHRD_PPP;
928 dev->mtu = card->wandev.mtu;
929 /* for API usage, add the API header size to the requested MTU size */
930 if(card->u.c.usedby == API) {
931 dev->mtu += sizeof(api_tx_hdr_t);
934 dev->hard_header_len = CHDLC_HDR_LEN;
936 /* Initialize hardware parameters */
937 dev->irq = wandev->irq;
938 dev->dma = wandev->dma;
939 dev->base_addr = wandev->ioport;
940 dev->mem_start = wandev->maddr;
941 dev->mem_end = wandev->maddr + wandev->msize - 1;
943 /* Set transmit buffer queue length
944 * If too low packets will not be retransmitted
945 * by stack.
947 dev->tx_queue_len = 100;
948 SET_MODULE_OWNER(dev);
950 return 0;
953 /*============================================================================
954 * Open network interface.
955 * o enable communications and interrupts.
956 * o prevent module from unloading by incrementing use count
958 * Return 0 if O.k. or errno.
960 static int if_open(struct net_device* dev)
962 chdlc_private_area_t* chdlc_priv_area = dev->priv;
963 sdla_t* card = chdlc_priv_area->card;
964 struct timeval tv;
965 int err = 0;
967 /* Only one open per interface is allowed */
969 if (netif_running(dev))
970 return -EBUSY;
972 /* Initialize the work queue entry */
973 chdlc_priv_area->tq_working=0;
975 INIT_WORK(&chdlc_priv_area->common.wanpipe_work,
976 (void *)(void *)chdlc_work, dev);
978 /* Allocate and initialize BH circular buffer */
979 /* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */
980 chdlc_priv_area->bh_head = kmalloc((sizeof(bh_data_t)*(MAX_BH_BUFF+1)),GFP_ATOMIC);
981 memset(chdlc_priv_area->bh_head,0,(sizeof(bh_data_t)*(MAX_BH_BUFF+1)));
982 atomic_set(&chdlc_priv_area->bh_buff_used, 0);
984 do_gettimeofday(&tv);
985 chdlc_priv_area->router_start_time = tv.tv_sec;
987 netif_start_queue(dev);
989 wanpipe_open(card);
991 /* TTY is configured during wanpipe_set_termios
992 * call, not here */
993 if (card->tty_opt)
994 return err;
996 set_bit(0,&chdlc_priv_area->config_chdlc);
997 chdlc_priv_area->config_chdlc_timeout=jiffies;
999 /* Start the CHDLC configuration after 1sec delay.
1000 * This will give the interface initilization time
1001 * to finish its configuration */
1002 mod_timer(&chdlc_priv_area->poll_delay_timer, jiffies + HZ);
1003 return err;
1006 /*============================================================================
1007 * Close network interface.
1008 * o if this is the last close, then disable communications and interrupts.
1009 * o reset flags.
1011 static int if_close(struct net_device* dev)
1013 chdlc_private_area_t* chdlc_priv_area = dev->priv;
1014 sdla_t* card = chdlc_priv_area->card;
1016 if (chdlc_priv_area->bh_head){
1017 int i;
1018 struct sk_buff *skb;
1020 for (i=0; i<(MAX_BH_BUFF+1); i++){
1021 skb = ((bh_data_t *)&chdlc_priv_area->bh_head[i])->skb;
1022 if (skb != NULL){
1023 dev_kfree_skb_any(skb);
1026 kfree(chdlc_priv_area->bh_head);
1027 chdlc_priv_area->bh_head=NULL;
1030 netif_stop_queue(dev);
1031 wanpipe_close(card);
1032 del_timer(&chdlc_priv_area->poll_delay_timer);
1033 return 0;
1036 static void disable_comm (sdla_t *card)
1038 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1040 if (card->u.c.comm_enabled){
1041 chdlc_disable_comm_shutdown (card);
1042 }else{
1043 flags->interrupt_info_struct.interrupt_permission = 0;
1046 if (!tty_init_cnt)
1047 return;
1049 if (card->tty_opt){
1050 struct serial_state * state;
1051 if (!(--tty_init_cnt)){
1052 int e1;
1053 serial_driver.refcount=0;
1055 if ((e1 = tty_unregister_driver(&serial_driver)))
1056 printk("SERIAL: failed to unregister serial driver (%d)\n",
1057 e1);
1058 printk(KERN_INFO "%s: Unregistering TTY Driver, Major %i\n",
1059 card->devname,WAN_TTY_MAJOR);
1061 card->tty=NULL;
1062 tty_card_map[card->tty_minor]=NULL;
1063 state = &rs_table[card->tty_minor];
1064 memset(state, 0, sizeof(*state));
1066 return;
1070 /*============================================================================
1071 * Build media header.
1073 * The trick here is to put packet type (Ethertype) into 'protocol' field of
1074 * the socket buffer, so that we don't forget it. If packet type is not
1075 * supported, set skb->protocol to 0 and discard packet later.
1077 * Return: media header length.
1079 static int if_header(struct sk_buff* skb, struct net_device* dev,
1080 unsigned short type, void* daddr, void* saddr,
1081 unsigned len)
1083 skb->protocol = htons(type);
1085 return CHDLC_HDR_LEN;
1089 /*============================================================================
1090 * Handle transmit timeout event from netif watchdog
1092 static void if_tx_timeout(struct net_device *dev)
1094 chdlc_private_area_t* chan = dev->priv;
1095 sdla_t *card = chan->card;
1097 /* If our device stays busy for at least 5 seconds then we will
1098 * kick start the device by making dev->tbusy = 0. We expect
1099 * that our device never stays busy more than 5 seconds. So this
1100 * is only used as a last resort.
1103 ++card->wandev.stats.collisions;
1105 printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
1106 netif_wake_queue (dev);
1111 /*============================================================================
1112 * Re-build media header.
1114 * Return: 1 physical address resolved.
1115 * 0 physical address not resolved
1117 static int if_rebuild_hdr (struct sk_buff *skb)
1119 return 1;
1123 /*============================================================================
1124 * Send a packet on a network interface.
1125 * o set tbusy flag (marks start of the transmission) to block a timer-based
1126 * transmit from overlapping.
1127 * o check link state. If link is not up, then drop the packet.
1128 * o execute adapter send command.
1129 * o free socket buffer
1131 * Return: 0 complete (socket buffer must be freed)
1132 * non-0 packet may be re-transmitted (tbusy must be set)
1134 * Notes:
1135 * 1. This routine is called either by the protocol stack or by the "net
1136 * bottom half" (with interrupts enabled).
1137 * 2. Setting tbusy flag will inhibit further transmit requests from the
1138 * protocol stack and can be used for flow control with protocol layer.
1140 static int if_send(struct sk_buff* skb, struct net_device* dev)
1142 chdlc_private_area_t *chdlc_priv_area = dev->priv;
1143 sdla_t *card = chdlc_priv_area->card;
1144 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1145 INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
1146 int udp_type = 0;
1147 unsigned long smp_flags;
1148 int err=0;
1150 netif_stop_queue(dev);
1152 if (skb == NULL){
1153 /* If we get here, some higher layer thinks we've missed an
1154 * tx-done interrupt.
1156 printk(KERN_INFO "%s: interface %s got kicked!\n",
1157 card->devname, dev->name);
1159 netif_wake_queue(dev);
1160 return 0;
1163 if (ntohs(skb->protocol) != htons(PVC_PROT)){
1165 /* check the udp packet type */
1167 udp_type = udp_pkt_type(skb, card);
1169 if (udp_type == UDP_CPIPE_TYPE){
1170 if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
1171 chdlc_priv_area)){
1172 chdlc_int->interrupt_permission |=
1173 APP_INT_ON_TIMER;
1175 netif_start_queue(dev);
1176 return 0;
1179 /* check to see if the source IP address is a broadcast or */
1180 /* multicast IP address */
1181 if(chk_bcast_mcast_addr(card, dev, skb)){
1182 ++card->wandev.stats.tx_dropped;
1183 dev_kfree_skb_any(skb);
1184 netif_start_queue(dev);
1185 return 0;
1189 /* Lock the 508 Card: SMP is supported */
1190 if(card->hw.type != SDLA_S514){
1191 s508_lock(card,&smp_flags);
1194 if(test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
1196 printk(KERN_INFO "%s: Critical in if_send: %lx\n",
1197 card->wandev.name,card->wandev.critical);
1198 ++card->wandev.stats.tx_dropped;
1199 netif_start_queue(dev);
1200 goto if_send_exit_crit;
1203 if(card->u.c.state != WAN_CONNECTED){
1204 ++card->wandev.stats.tx_dropped;
1205 netif_start_queue(dev);
1207 }else if(!skb->protocol){
1208 ++card->wandev.stats.tx_errors;
1209 netif_start_queue(dev);
1211 }else {
1212 void* data = skb->data;
1213 unsigned len = skb->len;
1214 unsigned char attr;
1216 /* If it's an API packet pull off the API
1217 * header. Also check that the packet size
1218 * is larger than the API header
1220 if (card->u.c.usedby == API){
1221 api_tx_hdr_t* api_tx_hdr;
1223 /* discard the frame if we are configured for */
1224 /* 'receive only' mode or if there is no data */
1225 if (card->u.c.receive_only ||
1226 (len <= sizeof(api_tx_hdr_t))) {
1228 ++card->wandev.stats.tx_dropped;
1229 netif_start_queue(dev);
1230 goto if_send_exit_crit;
1233 api_tx_hdr = (api_tx_hdr_t *)data;
1234 attr = api_tx_hdr->attr;
1235 data += sizeof(api_tx_hdr_t);
1236 len -= sizeof(api_tx_hdr_t);
1239 if(chdlc_send(card, data, len)) {
1240 netif_stop_queue(dev);
1241 }else{
1242 ++card->wandev.stats.tx_packets;
1243 card->wandev.stats.tx_bytes += len;
1245 netif_start_queue(dev);
1247 dev->trans_start = jiffies;
1251 if_send_exit_crit:
1253 if (!(err=netif_queue_stopped(dev))) {
1254 dev_kfree_skb_any(skb);
1255 }else{
1256 chdlc_priv_area->tick_counter = jiffies;
1257 chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
1260 clear_bit(SEND_CRIT, (void*)&card->wandev.critical);
1261 if(card->hw.type != SDLA_S514){
1262 s508_unlock(card,&smp_flags);
1265 return err;
1269 /*============================================================================
1270 * Check to see if the packet to be transmitted contains a broadcast or
1271 * multicast source IP address.
1274 static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
1275 struct sk_buff *skb)
1277 u32 src_ip_addr;
1278 u32 broadcast_ip_addr = 0;
1279 struct in_device *in_dev;
1281 /* read the IP source address from the outgoing packet */
1282 src_ip_addr = *(u32 *)(skb->data + 12);
1284 /* read the IP broadcast address for the device */
1285 in_dev = dev->ip_ptr;
1286 if(in_dev != NULL) {
1287 struct in_ifaddr *ifa= in_dev->ifa_list;
1288 if(ifa != NULL)
1289 broadcast_ip_addr = ifa->ifa_broadcast;
1290 else
1291 return 0;
1294 /* check if the IP Source Address is a Broadcast address */
1295 if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {
1296 printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n",
1297 card->devname);
1298 return 1;
1301 /* check if the IP Source Address is a Multicast address */
1302 if((ntohl(src_ip_addr) >= 0xE0000001) &&
1303 (ntohl(src_ip_addr) <= 0xFFFFFFFE)) {
1304 printk(KERN_INFO "%s: Multicast Source Address silently discarded\n",
1305 card->devname);
1306 return 1;
1309 return 0;
1313 /*============================================================================
1314 * Reply to UDP Management system.
1315 * Return length of reply.
1317 static int reply_udp( unsigned char *data, unsigned int mbox_len )
1320 unsigned short len, udp_length, temp, ip_length;
1321 unsigned long ip_temp;
1322 int even_bound = 0;
1323 chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data;
1325 /* Set length of packet */
1326 len = sizeof(ip_pkt_t)+
1327 sizeof(udp_pkt_t)+
1328 sizeof(wp_mgmt_t)+
1329 sizeof(cblock_t)+
1330 sizeof(trace_info_t)+
1331 mbox_len;
1333 /* fill in UDP reply */
1334 c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
1336 /* fill in UDP length */
1337 udp_length = sizeof(udp_pkt_t)+
1338 sizeof(wp_mgmt_t)+
1339 sizeof(cblock_t)+
1340 sizeof(trace_info_t)+
1341 mbox_len;
1343 /* put it on an even boundary */
1344 if ( udp_length & 0x0001 ) {
1345 udp_length += 1;
1346 len += 1;
1347 even_bound = 1;
1350 temp = (udp_length<<8)|(udp_length>>8);
1351 c_udp_pkt->udp_pkt.udp_length = temp;
1353 /* swap UDP ports */
1354 temp = c_udp_pkt->udp_pkt.udp_src_port;
1355 c_udp_pkt->udp_pkt.udp_src_port =
1356 c_udp_pkt->udp_pkt.udp_dst_port;
1357 c_udp_pkt->udp_pkt.udp_dst_port = temp;
1359 /* add UDP pseudo header */
1360 temp = 0x1100;
1361 *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp;
1362 temp = (udp_length<<8)|(udp_length>>8);
1363 *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp;
1366 /* calculate UDP checksum */
1367 c_udp_pkt->udp_pkt.udp_checksum = 0;
1368 c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
1370 /* fill in IP length */
1371 ip_length = len;
1372 temp = (ip_length<<8)|(ip_length>>8);
1373 c_udp_pkt->ip_pkt.total_length = temp;
1375 /* swap IP addresses */
1376 ip_temp = c_udp_pkt->ip_pkt.ip_src_address;
1377 c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address;
1378 c_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
1380 /* fill in IP checksum */
1381 c_udp_pkt->ip_pkt.hdr_checksum = 0;
1382 c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));
1384 return len;
1386 } /* reply_udp */
1388 unsigned short calc_checksum (char *data, int len)
1390 unsigned short temp;
1391 unsigned long sum=0;
1392 int i;
1394 for( i = 0; i <len; i+=2 ) {
1395 memcpy(&temp,&data[i],2);
1396 sum += (unsigned long)temp;
1399 while (sum >> 16 ) {
1400 sum = (sum & 0xffffUL) + (sum >> 16);
1403 temp = (unsigned short)sum;
1404 temp = ~temp;
1406 if( temp == 0 )
1407 temp = 0xffff;
1409 return temp;
1413 /*============================================================================
1414 * Get ethernet-style interface statistics.
1415 * Return a pointer to struct enet_statistics.
1417 static struct net_device_stats* if_stats(struct net_device* dev)
1419 sdla_t *my_card;
1420 chdlc_private_area_t* chdlc_priv_area;
1422 if ((chdlc_priv_area=dev->priv) == NULL)
1423 return NULL;
1425 my_card = chdlc_priv_area->card;
1426 return &my_card->wandev.stats;
1430 /****** Cisco HDLC Firmware Interface Functions *******************************/
1432 /*============================================================================
1433 * Read firmware code version.
1434 * Put code version as ASCII string in str.
1436 static int chdlc_read_version (sdla_t* card, char* str)
1438 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1439 int len;
1440 char err;
1441 mb->buffer_length = 0;
1442 mb->command = READ_CHDLC_CODE_VERSION;
1443 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1445 if(err != COMMAND_OK) {
1446 chdlc_error(card,err,mb);
1448 else if (str) { /* is not null */
1449 len = mb->buffer_length;
1450 memcpy(str, mb->data, len);
1451 str[len] = '\0';
1453 return (err);
1456 /*-----------------------------------------------------------------------------
1457 * Configure CHDLC firmware.
1459 static int chdlc_configure (sdla_t* card, void* data)
1461 int err;
1462 CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
1463 int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);
1465 mailbox->buffer_length = data_length;
1466 memcpy(mailbox->data, data, data_length);
1467 mailbox->command = SET_CHDLC_CONFIGURATION;
1468 err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
1470 if (err != COMMAND_OK) chdlc_error (card, err, mailbox);
1472 return err;
1476 /*============================================================================
1477 * Set interrupt mode -- HDLC Version.
1480 static int chdlc_set_intr_mode (sdla_t* card, unsigned mode)
1482 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1483 CHDLC_INT_TRIGGERS_STRUCT* int_data =
1484 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1485 int err;
1487 int_data->CHDLC_interrupt_triggers = mode;
1488 int_data->IRQ = card->hw.irq;
1489 int_data->interrupt_timer = 1;
1491 mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
1492 mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
1493 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1494 if (err != COMMAND_OK)
1495 chdlc_error (card, err, mb);
1496 return err;
1500 /*===========================================================
1501 * chdlc_disable_comm_shutdown
1503 * Shutdown() disables the communications. We must
1504 * have a sparate functions, because we must not
1505 * call chdlc_error() hander since the private
1506 * area has already been replaced */
1508 static int chdlc_disable_comm_shutdown (sdla_t *card)
1510 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1511 CHDLC_INT_TRIGGERS_STRUCT* int_data =
1512 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1513 int err;
1515 /* Disable Interrutps */
1516 int_data->CHDLC_interrupt_triggers = 0;
1517 int_data->IRQ = card->hw.irq;
1518 int_data->interrupt_timer = 1;
1520 mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
1521 mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
1522 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1524 /* Disable Communications */
1526 if (card->u.c.async_mode) {
1527 mb->command = DISABLE_ASY_COMMUNICATIONS;
1528 }else{
1529 mb->command = DISABLE_CHDLC_COMMUNICATIONS;
1532 mb->buffer_length = 0;
1533 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1535 card->u.c.comm_enabled = 0;
1537 return 0;
1540 /*============================================================================
1541 * Enable communications.
1544 static int chdlc_comm_enable (sdla_t* card)
1546 int err;
1547 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1549 mb->buffer_length = 0;
1550 mb->command = ENABLE_CHDLC_COMMUNICATIONS;
1551 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1552 if (err != COMMAND_OK)
1553 chdlc_error(card, err, mb);
1554 else
1555 card->u.c.comm_enabled = 1;
1557 return err;
1560 /*============================================================================
1561 * Read communication error statistics.
1563 static int chdlc_read_comm_err_stats (sdla_t* card)
1565 int err;
1566 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1568 mb->buffer_length = 0;
1569 mb->command = READ_COMMS_ERROR_STATS;
1570 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1571 if (err != COMMAND_OK)
1572 chdlc_error(card,err,mb);
1573 return err;
1577 /*============================================================================
1578 * Read CHDLC operational statistics.
1580 static int chdlc_read_op_stats (sdla_t* card)
1582 int err;
1583 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1585 mb->buffer_length = 0;
1586 mb->command = READ_CHDLC_OPERATIONAL_STATS;
1587 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1588 if (err != COMMAND_OK)
1589 chdlc_error(card,err,mb);
1590 return err;
1594 /*============================================================================
1595 * Update communications error and general packet statistics.
1597 static int update_comms_stats(sdla_t* card,
1598 chdlc_private_area_t* chdlc_priv_area)
1600 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1601 COMMS_ERROR_STATS_STRUCT* err_stats;
1602 CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;
1604 /* on the first timer interrupt, read the comms error statistics */
1605 if(chdlc_priv_area->update_comms_stats == 2) {
1606 if(chdlc_read_comm_err_stats(card))
1607 return 1;
1608 err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data;
1609 card->wandev.stats.rx_over_errors =
1610 err_stats->Rx_overrun_err_count;
1611 card->wandev.stats.rx_crc_errors =
1612 err_stats->CRC_err_count;
1613 card->wandev.stats.rx_frame_errors =
1614 err_stats->Rx_abort_count;
1615 card->wandev.stats.rx_fifo_errors =
1616 err_stats->Rx_dis_pri_bfrs_full_count;
1617 card->wandev.stats.rx_missed_errors =
1618 card->wandev.stats.rx_fifo_errors;
1619 card->wandev.stats.tx_aborted_errors =
1620 err_stats->sec_Tx_abort_count;
1623 /* on the second timer interrupt, read the operational statistics */
1624 else {
1625 if(chdlc_read_op_stats(card))
1626 return 1;
1627 op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data;
1628 card->wandev.stats.rx_length_errors =
1629 (op_stats->Rx_Data_discard_short_count +
1630 op_stats->Rx_Data_discard_long_count);
1633 return 0;
1636 /*============================================================================
1637 * Send packet.
1638 * Return: 0 - o.k.
1639 * 1 - no transmit buffers available
1641 static int chdlc_send (sdla_t* card, void* data, unsigned len)
1643 CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;
1645 if (txbuf->opp_flag)
1646 return 1;
1648 sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);
1650 txbuf->frame_length = len;
1651 txbuf->opp_flag = 1; /* start transmission */
1653 /* Update transmit buffer control fields */
1654 card->u.c.txbuf = ++txbuf;
1656 if ((void*)txbuf > card->u.c.txbuf_last)
1657 card->u.c.txbuf = card->u.c.txbuf_base;
1659 return 0;
1662 /****** Firmware Error Handler **********************************************/
1664 /*============================================================================
1665 * Firmware error handler.
1666 * This routine is called whenever firmware command returns non-zero
1667 * return code.
1669 * Return zero if previous command has to be cancelled.
1671 static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
1673 unsigned cmd = mb->command;
1675 switch (err) {
1677 case CMD_TIMEOUT:
1678 printk(KERN_INFO "%s: command 0x%02X timed out!\n",
1679 card->devname, cmd);
1680 break;
1682 case S514_BOTH_PORTS_SAME_CLK_MODE:
1683 if(cmd == SET_CHDLC_CONFIGURATION) {
1684 printk(KERN_INFO
1685 "%s: Configure both ports for the same clock source\n",
1686 card->devname);
1687 break;
1690 default:
1691 printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
1692 card->devname, cmd, err);
1695 return 0;
1699 /********** Bottom Half Handlers ********************************************/
1701 /* NOTE: There is no API, BH support for Kernels lower than 2.2.X.
1702 * DO NOT INSERT ANY CODE HERE, NOTICE THE
1703 * PREPROCESSOR STATEMENT ABOVE, UNLESS YOU KNOW WHAT YOU ARE
1704 * DOING */
1706 static void chdlc_work(struct net_device * dev)
1708 chdlc_private_area_t* chan = dev->priv;
1709 sdla_t *card = chan->card;
1710 struct sk_buff *skb;
1712 if (atomic_read(&chan->bh_buff_used) == 0){
1713 clear_bit(0, &chan->tq_working);
1714 return;
1717 while (atomic_read(&chan->bh_buff_used)){
1719 skb = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb;
1721 if (skb != NULL){
1723 if (chan->common.sk == NULL || chan->common.func == NULL){
1724 ++card->wandev.stats.rx_dropped;
1725 dev_kfree_skb_any(skb);
1726 chdlc_work_cleanup(dev);
1727 continue;
1730 if (chan->common.func(skb,dev,chan->common.sk) != 0){
1731 /* Sock full cannot send, queue us for another
1732 * try */
1733 atomic_set(&chan->common.receive_block,1);
1734 return;
1735 }else{
1736 chdlc_work_cleanup(dev);
1738 }else{
1739 chdlc_work_cleanup(dev);
1742 clear_bit(0, &chan->tq_working);
1744 return;
1747 static int chdlc_work_cleanup(struct net_device *dev)
1749 chdlc_private_area_t* chan = dev->priv;
1751 ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL;
1753 if (chan->bh_read == MAX_BH_BUFF){
1754 chan->bh_read=0;
1755 }else{
1756 ++chan->bh_read;
1759 atomic_dec(&chan->bh_buff_used);
1760 return 0;
1765 static int bh_enqueue(struct net_device *dev, struct sk_buff *skb)
1767 /* Check for full */
1768 chdlc_private_area_t* chan = dev->priv;
1769 sdla_t *card = chan->card;
1771 if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){
1772 ++card->wandev.stats.rx_dropped;
1773 dev_kfree_skb_any(skb);
1774 return 1;
1777 ((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb;
1779 if (chan->bh_write == MAX_BH_BUFF){
1780 chan->bh_write=0;
1781 }else{
1782 ++chan->bh_write;
1785 atomic_inc(&chan->bh_buff_used);
1787 return 0;
1790 /* END OF API BH Support */
1793 /****** Interrupt Handlers **************************************************/
1795 /*============================================================================
1796 * Cisco HDLC interrupt service routine.
1798 static void wpc_isr (sdla_t* card)
1800 struct net_device* dev;
1801 SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1802 int i;
1803 sdla_t *my_card;
1806 /* Check for which port the interrupt has been generated
1807 * Since Secondary Port is piggybacking on the Primary
1808 * the check must be done here.
1811 flags = card->u.c.flags;
1812 if (!flags->interrupt_info_struct.interrupt_type){
1813 /* Check for a second port (piggybacking) */
1814 if ((my_card = card->next)){
1815 flags = my_card->u.c.flags;
1816 if (flags->interrupt_info_struct.interrupt_type){
1817 card = my_card;
1818 card->isr(card);
1819 return;
1824 flags = card->u.c.flags;
1825 card->in_isr = 1;
1826 dev = card->wandev.dev;
1828 /* If we get an interrupt with no network device, stop the interrupts
1829 * and issue an error */
1830 if (!card->tty_opt && !dev &&
1831 flags->interrupt_info_struct.interrupt_type !=
1832 COMMAND_COMPLETE_APP_INT_PEND){
1834 goto isr_done;
1837 /* if critical due to peripheral operations
1838 * ie. update() or getstats() then reset the interrupt and
1839 * wait for the board to retrigger.
1841 if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
1842 printk(KERN_INFO "ISR CRIT TO PERI\n");
1843 goto isr_done;
1846 /* On a 508 Card, if critical due to if_send
1847 * Major Error !!! */
1848 if(card->hw.type != SDLA_S514) {
1849 if(test_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
1850 printk(KERN_INFO "%s: Critical while in ISR: %lx\n",
1851 card->devname, card->wandev.critical);
1852 card->in_isr = 0;
1853 flags->interrupt_info_struct.interrupt_type = 0;
1854 return;
1858 switch(flags->interrupt_info_struct.interrupt_type) {
1860 case RX_APP_INT_PEND: /* 0x01: receive interrupt */
1861 rx_intr(card);
1862 break;
1864 case TX_APP_INT_PEND: /* 0x02: transmit interrupt */
1865 flags->interrupt_info_struct.interrupt_permission &=
1866 ~APP_INT_ON_TX_FRAME;
1868 if (card->tty_opt){
1869 wanpipe_tty_trigger_poll(card);
1870 break;
1873 if (dev && netif_queue_stopped(dev)){
1874 if (card->u.c.usedby == API){
1875 netif_start_queue(dev);
1876 wakeup_sk_bh(dev);
1877 }else{
1878 netif_wake_queue(dev);
1881 break;
1883 case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
1884 ++ Intr_test_counter;
1885 break;
1887 case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */
1888 process_chdlc_exception(card);
1889 break;
1891 case GLOBAL_EXCEP_COND_APP_INT_PEND:
1892 process_global_exception(card);
1893 break;
1895 case TIMER_APP_INT_PEND:
1896 timer_intr(card);
1897 break;
1899 default:
1900 printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n",
1901 card->devname,
1902 flags->interrupt_info_struct.interrupt_type);
1903 printk(KERN_INFO "Code name: ");
1904 for(i = 0; i < 4; i ++)
1905 printk(KERN_INFO "%c",
1906 flags->global_info_struct.codename[i]);
1907 printk(KERN_INFO "\nCode version: ");
1908 for(i = 0; i < 4; i ++)
1909 printk(KERN_INFO "%c",
1910 flags->global_info_struct.codeversion[i]);
1911 printk(KERN_INFO "\n");
1912 break;
1915 isr_done:
1917 card->in_isr = 0;
1918 flags->interrupt_info_struct.interrupt_type = 0;
1919 return;
1922 /*============================================================================
1923 * Receive interrupt handler.
1925 static void rx_intr (sdla_t* card)
1927 struct net_device *dev;
1928 chdlc_private_area_t *chdlc_priv_area;
1929 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1930 CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
1931 struct sk_buff *skb;
1932 unsigned len;
1933 unsigned addr = rxbuf->ptr_data_bfr;
1934 void *buf;
1935 int i,udp_type;
1937 if (rxbuf->opp_flag != 0x01) {
1938 printk(KERN_INFO
1939 "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
1940 card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
1941 printk(KERN_INFO "Code name: ");
1942 for(i = 0; i < 4; i ++)
1943 printk(KERN_INFO "%c",
1944 flags->global_info_struct.codename[i]);
1945 printk(KERN_INFO "\nCode version: ");
1946 for(i = 0; i < 4; i ++)
1947 printk(KERN_INFO "%c",
1948 flags->global_info_struct.codeversion[i]);
1949 printk(KERN_INFO "\n");
1952 /* Bug Fix: Mar 6 2000
1953 * If we get a corrupted mailbox, it measn that driver
1954 * is out of sync with the firmware. There is no recovery.
1955 * If we don't turn off all interrupts for this card
1956 * the machine will crash.
1958 printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
1959 printk(KERN_INFO "Please contact Sangoma Technologies !\n");
1960 chdlc_set_intr_mode(card,0);
1961 return;
1964 len = rxbuf->frame_length;
1966 if (card->tty_opt){
1968 if (rxbuf->error_flag){
1969 goto rx_exit;
1972 if (len <= CRC_LENGTH){
1973 goto rx_exit;
1976 if (!card->u.c.async_mode){
1977 len -= CRC_LENGTH;
1980 wanpipe_tty_receive(card,addr,len);
1981 goto rx_exit;
1984 dev = card->wandev.dev;
1986 if (!dev){
1987 goto rx_exit;
1990 if (!netif_running(dev))
1991 goto rx_exit;
1993 chdlc_priv_area = dev->priv;
1996 /* Allocate socket buffer */
1997 skb = dev_alloc_skb(len);
1999 if (skb == NULL) {
2000 printk(KERN_INFO "%s: no socket buffers available!\n",
2001 card->devname);
2002 ++card->wandev.stats.rx_dropped;
2003 goto rx_exit;
2006 /* Copy data to the socket buffer */
2007 if((addr + len) > card->u.c.rx_top + 1) {
2008 unsigned tmp = card->u.c.rx_top - addr + 1;
2009 buf = skb_put(skb, tmp);
2010 sdla_peek(&card->hw, addr, buf, tmp);
2011 addr = card->u.c.rx_base;
2012 len -= tmp;
2015 buf = skb_put(skb, len);
2016 sdla_peek(&card->hw, addr, buf, len);
2018 skb->protocol = htons(ETH_P_IP);
2020 card->wandev.stats.rx_packets ++;
2021 card->wandev.stats.rx_bytes += skb->len;
2022 udp_type = udp_pkt_type( skb, card );
2024 if(udp_type == UDP_CPIPE_TYPE) {
2025 if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
2026 card, skb, dev, chdlc_priv_area)) {
2027 flags->interrupt_info_struct.
2028 interrupt_permission |=
2029 APP_INT_ON_TIMER;
2031 } else if(card->u.c.usedby == API) {
2033 api_rx_hdr_t* api_rx_hdr;
2034 skb_push(skb, sizeof(api_rx_hdr_t));
2035 api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00];
2036 api_rx_hdr->error_flag = rxbuf->error_flag;
2037 api_rx_hdr->time_stamp = rxbuf->time_stamp;
2039 skb->protocol = htons(PVC_PROT);
2040 skb->mac.raw = skb->data;
2041 skb->dev = dev;
2042 skb->pkt_type = WAN_PACKET_DATA;
2044 bh_enqueue(dev, skb);
2046 if (!test_and_set_bit(0,&chdlc_priv_area->tq_working))
2047 wanpipe_queue_work(&chdlc_priv_area->common.wanpipe_work);
2048 }else{
2049 /* FIXME: we should check to see if the received packet is a
2050 multicast packet so that we can increment the multicast
2051 statistic
2052 ++ chdlc_priv_area->if_stats.multicast;
2054 /* Pass it up the protocol stack */
2056 skb->dev = dev;
2057 skb->mac.raw = skb->data;
2058 netif_rx(skb);
2059 dev->last_rx = jiffies;
2062 rx_exit:
2063 /* Release buffer element and calculate a pointer to the next one */
2064 rxbuf->opp_flag = 0x00;
2065 card->u.c.rxmb = ++ rxbuf;
2066 if((void*)rxbuf > card->u.c.rxbuf_last){
2067 card->u.c.rxmb = card->u.c.rxbuf_base;
2071 /*============================================================================
2072 * Timer interrupt handler.
2073 * The timer interrupt is used for two purposes:
2074 * 1) Processing udp calls from 'cpipemon'.
2075 * 2) Reading board-level statistics for updating the proc file system.
2077 void timer_intr(sdla_t *card)
2079 struct net_device* dev;
2080 chdlc_private_area_t* chdlc_priv_area = NULL;
2081 SHARED_MEMORY_INFO_STRUCT* flags = NULL;
2083 if ((dev = card->wandev.dev)==NULL){
2084 flags = card->u.c.flags;
2085 flags->interrupt_info_struct.interrupt_permission &=
2086 ~APP_INT_ON_TIMER;
2087 return;
2090 chdlc_priv_area = dev->priv;
2092 if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) {
2093 if (!config_chdlc(card)){
2094 chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
2098 /* process a udp call if pending */
2099 if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
2100 process_udp_mgmt_pkt(card, dev,
2101 chdlc_priv_area);
2102 chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
2105 /* read the communications statistics if required */
2106 if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
2107 update_comms_stats(card, chdlc_priv_area);
2108 if(!(-- chdlc_priv_area->update_comms_stats)) {
2109 chdlc_priv_area->timer_int_enabled &=
2110 ~TMR_INT_ENABLED_UPDATE;
2114 /* only disable the timer interrupt if there are no udp or statistic */
2115 /* updates pending */
2116 if(!chdlc_priv_area->timer_int_enabled) {
2117 flags = card->u.c.flags;
2118 flags->interrupt_info_struct.interrupt_permission &=
2119 ~APP_INT_ON_TIMER;
2123 /*------------------------------------------------------------------------------
2124 Miscellaneous Functions
2125 - set_chdlc_config() used to set configuration options on the board
2126 ------------------------------------------------------------------------------*/
2128 static int set_chdlc_config(sdla_t* card)
2130 CHDLC_CONFIGURATION_STRUCT cfg;
2132 memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
2134 if(card->wandev.clocking){
2135 cfg.baud_rate = card->wandev.bps;
2138 cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
2139 INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
2141 cfg.modem_config_options = 0;
2142 cfg.modem_status_timer = 100;
2144 cfg.CHDLC_protocol_options = card->u.c.protocol_options;
2146 if (card->tty_opt){
2147 cfg.CHDLC_API_options = DISCARD_RX_ERROR_FRAMES;
2150 cfg.percent_data_buffer_for_Tx = (card->u.c.receive_only) ? 0 : 50;
2151 cfg.CHDLC_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT |
2152 CHDLC_RX_DATA_BYTE_COUNT_STAT);
2154 if (card->tty_opt){
2155 card->wandev.mtu = TTY_CHDLC_MAX_MTU;
2157 cfg.max_CHDLC_data_field_length = card->wandev.mtu;
2158 cfg.transmit_keepalive_timer = card->u.c.kpalv_tx;
2159 cfg.receive_keepalive_timer = card->u.c.kpalv_rx;
2160 cfg.keepalive_error_tolerance = card->u.c.kpalv_err;
2161 cfg.SLARP_request_timer = card->u.c.slarp_timer;
2163 if (cfg.SLARP_request_timer) {
2164 cfg.IP_address = 0;
2165 cfg.IP_netmask = 0;
2167 }else if (card->wandev.dev){
2168 struct net_device *dev = card->wandev.dev;
2169 chdlc_private_area_t *chdlc_priv_area = dev->priv;
2171 struct in_device *in_dev = dev->ip_ptr;
2173 if(in_dev != NULL) {
2174 struct in_ifaddr *ifa = in_dev->ifa_list;
2176 if (ifa != NULL ) {
2177 cfg.IP_address = ntohl(ifa->ifa_local);
2178 cfg.IP_netmask = ntohl(ifa->ifa_mask);
2179 chdlc_priv_area->IP_address = ntohl(ifa->ifa_local);
2180 chdlc_priv_area->IP_netmask = ntohl(ifa->ifa_mask);
2184 /* FIXME: We must re-think this message in next release
2185 if((cfg.IP_address & 0x000000FF) > 2) {
2186 printk(KERN_WARNING "\n");
2187 printk(KERN_WARNING " WARNING:%s configured with an\n",
2188 card->devname);
2189 printk(KERN_WARNING " invalid local IP address.\n");
2190 printk(KERN_WARNING " Slarp pragmatics will fail.\n");
2191 printk(KERN_WARNING " IP address should be of the\n");
2192 printk(KERN_WARNING " format A.B.C.1 or A.B.C.2.\n");
2197 return chdlc_configure(card, &cfg);
2201 /*-----------------------------------------------------------------------------
2202 set_asy_config() used to set asynchronous configuration options on the board
2203 ------------------------------------------------------------------------------*/
2205 static int set_asy_config(sdla_t* card)
2208 ASY_CONFIGURATION_STRUCT cfg;
2209 CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
2210 int err;
2212 memset(&cfg, 0, sizeof(ASY_CONFIGURATION_STRUCT));
2214 if(card->wandev.clocking)
2215 cfg.baud_rate = card->wandev.bps;
2217 cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
2218 INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
2220 cfg.modem_config_options = 0;
2221 cfg.asy_API_options = card->u.c.api_options;
2222 cfg.asy_protocol_options = card->u.c.protocol_options;
2223 cfg.Tx_bits_per_char = card->u.c.tx_bits_per_char;
2224 cfg.Rx_bits_per_char = card->u.c.rx_bits_per_char;
2225 cfg.stop_bits = card->u.c.stop_bits;
2226 cfg.parity = card->u.c.parity;
2227 cfg.break_timer = card->u.c.break_timer;
2228 cfg.asy_Rx_inter_char_timer = card->u.c.inter_char_timer;
2229 cfg.asy_Rx_complete_length = card->u.c.rx_complete_length;
2230 cfg.XON_char = card->u.c.xon_char;
2231 cfg.XOFF_char = card->u.c.xoff_char;
2232 cfg.asy_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT |
2233 CHDLC_RX_DATA_BYTE_COUNT_STAT);
2235 mailbox->buffer_length = sizeof(ASY_CONFIGURATION_STRUCT);
2236 memcpy(mailbox->data, &cfg, mailbox->buffer_length);
2237 mailbox->command = SET_ASY_CONFIGURATION;
2238 err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
2239 if (err != COMMAND_OK)
2240 chdlc_error (card, err, mailbox);
2241 return err;
2244 /*============================================================================
2245 * Enable asynchronous communications.
2248 static int asy_comm_enable (sdla_t* card)
2251 int err;
2252 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2254 mb->buffer_length = 0;
2255 mb->command = ENABLE_ASY_COMMUNICATIONS;
2256 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2257 if (err != COMMAND_OK && card->wandev.dev)
2258 chdlc_error(card, err, mb);
2260 if (!err)
2261 card->u.c.comm_enabled = 1;
2263 return err;
2266 /*============================================================================
2267 * Process global exception condition
2269 static int process_global_exception(sdla_t *card)
2271 CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
2272 int err;
2274 mbox->buffer_length = 0;
2275 mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
2276 err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
2278 if(err != CMD_TIMEOUT ){
2280 switch(mbox->return_code) {
2282 case EXCEP_MODEM_STATUS_CHANGE:
2284 printk(KERN_INFO "%s: Modem status change\n",
2285 card->devname);
2287 switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
2288 case (DCD_HIGH):
2289 printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname);
2290 break;
2291 case (CTS_HIGH):
2292 printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname);
2293 break;
2294 case ((DCD_HIGH | CTS_HIGH)):
2295 printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname);
2296 break;
2297 default:
2298 printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname);
2299 break;
2301 break;
2303 case EXCEP_TRC_DISABLED:
2304 printk(KERN_INFO "%s: Line trace disabled\n",
2305 card->devname);
2306 break;
2308 case EXCEP_IRQ_TIMEOUT:
2309 printk(KERN_INFO "%s: IRQ timeout occurred\n",
2310 card->devname);
2311 break;
2313 case 0x17:
2314 if (card->tty_opt){
2315 if (card->tty && card->tty_open){
2316 printk(KERN_INFO
2317 "%s: Modem Hangup Exception: Hanging Up!\n",
2318 card->devname);
2319 tty_hangup(card->tty);
2321 break;
2324 /* If TTY is not used just drop throught */
2326 default:
2327 printk(KERN_INFO "%s: Global exception %x\n",
2328 card->devname, mbox->return_code);
2329 break;
2332 return 0;
2336 /*============================================================================
2337 * Process chdlc exception condition
2339 static int process_chdlc_exception(sdla_t *card)
2341 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2342 int err;
2344 mb->buffer_length = 0;
2345 mb->command = READ_CHDLC_EXCEPTION_CONDITION;
2346 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2347 if(err != CMD_TIMEOUT) {
2349 switch (err) {
2351 case EXCEP_LINK_ACTIVE:
2352 port_set_state(card, WAN_CONNECTED);
2353 trigger_chdlc_poll(card->wandev.dev);
2354 break;
2356 case EXCEP_LINK_INACTIVE_MODEM:
2357 port_set_state(card, WAN_DISCONNECTED);
2358 unconfigure_ip(card);
2359 trigger_chdlc_poll(card->wandev.dev);
2360 break;
2362 case EXCEP_LINK_INACTIVE_KPALV:
2363 port_set_state(card, WAN_DISCONNECTED);
2364 printk(KERN_INFO "%s: Keepalive timer expired.\n",
2365 card->devname);
2366 unconfigure_ip(card);
2367 trigger_chdlc_poll(card->wandev.dev);
2368 break;
2370 case EXCEP_IP_ADDRESS_DISCOVERED:
2371 if (configure_ip(card))
2372 return -1;
2373 break;
2375 case EXCEP_LOOPBACK_CONDITION:
2376 printk(KERN_INFO "%s: Loopback Condition Detected.\n",
2377 card->devname);
2378 break;
2380 case NO_CHDLC_EXCEP_COND_TO_REPORT:
2381 printk(KERN_INFO "%s: No exceptions reported.\n",
2382 card->devname);
2383 break;
2387 return 0;
2391 /*============================================================================
2392 * Configure IP from SLARP negotiation
2393 * This adds dynamic routes when SLARP has provided valid addresses
2396 static int configure_ip (sdla_t* card)
2398 struct net_device *dev = card->wandev.dev;
2399 chdlc_private_area_t *chdlc_priv_area;
2400 char err;
2402 if (!dev)
2403 return 0;
2405 chdlc_priv_area = dev->priv;
2408 /* set to discover */
2409 if(card->u.c.slarp_timer != 0x00) {
2410 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2411 CHDLC_CONFIGURATION_STRUCT *cfg;
2413 mb->buffer_length = 0;
2414 mb->command = READ_CHDLC_CONFIGURATION;
2415 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2417 if(err != COMMAND_OK) {
2418 chdlc_error(card,err,mb);
2419 return -1;
2422 cfg = (CHDLC_CONFIGURATION_STRUCT *)mb->data;
2423 chdlc_priv_area->IP_address = cfg->IP_address;
2424 chdlc_priv_area->IP_netmask = cfg->IP_netmask;
2426 /* Set flag to add route */
2427 chdlc_priv_area->route_status = ADD_ROUTE;
2429 /* The idea here is to add the route in the poll routine.
2430 This way, we aren't in interrupt context when adding routes */
2431 trigger_chdlc_poll(dev);
2434 return 0;
2438 /*============================================================================
2439 * Un-Configure IP negotiated by SLARP
2440 * This removes dynamic routes when the link becomes inactive.
2443 static int unconfigure_ip (sdla_t* card)
2445 struct net_device *dev = card->wandev.dev;
2446 chdlc_private_area_t *chdlc_priv_area;
2448 if (!dev)
2449 return 0;
2451 chdlc_priv_area= dev->priv;
2453 if (chdlc_priv_area->route_status == ROUTE_ADDED) {
2455 /* Note: If this function is called, the
2456 * port state has been DISCONNECTED. This state
2457 * change will trigger a poll_disconnected
2458 * function, that will check for this condition.
2460 chdlc_priv_area->route_status = REMOVE_ROUTE;
2463 return 0;
2466 /*============================================================================
2467 * Routine to add/remove routes
2468 * Called like a polling routine when Routes are flagged to be added/removed.
2471 static void process_route (sdla_t *card)
2473 struct net_device *dev = card->wandev.dev;
2474 unsigned char port_num;
2475 chdlc_private_area_t *chdlc_priv_area = NULL;
2476 u32 local_IP_addr = 0;
2477 u32 remote_IP_addr = 0;
2478 u32 IP_netmask, IP_addr;
2479 int err = 0;
2480 struct in_device *in_dev;
2481 mm_segment_t fs;
2482 struct ifreq if_info;
2483 struct sockaddr_in *if_data1, *if_data2;
2485 chdlc_priv_area = dev->priv;
2486 port_num = card->u.c.comm_port;
2488 /* Bug Fix Mar 16 2000
2489 * AND the IP address to the Mask before checking
2490 * the last two bits. */
2492 if((chdlc_priv_area->route_status == ADD_ROUTE) &&
2493 ((chdlc_priv_area->IP_address & ~chdlc_priv_area->IP_netmask) > 2)) {
2495 printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname);
2497 if(card->u.c.slarp_timer) {
2498 u32 addr_net = htonl(chdlc_priv_area->IP_address);
2500 printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u received\n",
2501 card->devname,
2502 NIPQUAD(addr_net));
2503 printk(KERN_INFO "%s: from remote station.\n",
2504 card->devname);
2506 }else{
2507 u32 addr_net = htonl(chdlc_priv_area->IP_address);
2509 printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u issued\n",
2510 card->devname,
2511 NIPQUAD(addr_net));
2512 printk(KERN_INFO "%s: to remote station. Local\n",
2513 card->devname);
2514 printk(KERN_INFO "%s: IP address must be A.B.C.1\n",
2515 card->devname);
2516 printk(KERN_INFO "%s: or A.B.C.2.\n",card->devname);
2519 /* remove the route due to the IP address error condition */
2520 chdlc_priv_area->route_status = REMOVE_ROUTE;
2521 err = 1;
2524 /* If we are removing a route with bad IP addressing, then use the */
2525 /* locally configured IP addresses */
2526 if((chdlc_priv_area->route_status == REMOVE_ROUTE) && err) {
2528 /* do not remove a bad route that has already been removed */
2529 if(chdlc_priv_area->route_removed) {
2530 return;
2533 in_dev = dev->ip_ptr;
2535 if(in_dev != NULL) {
2536 struct in_ifaddr *ifa = in_dev->ifa_list;
2537 if (ifa != NULL ) {
2538 local_IP_addr = ifa->ifa_local;
2539 IP_netmask = ifa->ifa_mask;
2542 }else{
2543 /* According to Cisco HDLC, if the point-to-point address is
2544 A.B.C.1, then we are the opposite (A.B.C.2), and vice-versa.
2546 IP_netmask = ntohl(chdlc_priv_area->IP_netmask);
2547 remote_IP_addr = ntohl(chdlc_priv_area->IP_address);
2550 /* If Netmask is 255.255.255.255 the local address
2551 * calculation will fail. Default it back to 255.255.255.0 */
2552 if (IP_netmask == 0xffffffff)
2553 IP_netmask &= 0x00ffffff;
2555 /* Bug Fix Mar 16 2000
2556 * AND the Remote IP address with IP netmask, instead
2557 * of static netmask of 255.255.255.0 */
2558 local_IP_addr = (remote_IP_addr & IP_netmask) +
2559 (~remote_IP_addr & ntohl(0x0003));
2561 if(!card->u.c.slarp_timer) {
2562 IP_addr = local_IP_addr;
2563 local_IP_addr = remote_IP_addr;
2564 remote_IP_addr = IP_addr;
2568 fs = get_fs(); /* Save file system */
2569 set_fs(get_ds()); /* Get user space block */
2571 /* Setup a structure for adding/removing routes */
2572 memset(&if_info, 0, sizeof(if_info));
2573 strcpy(if_info.ifr_name, dev->name);
2575 switch (chdlc_priv_area->route_status) {
2577 case ADD_ROUTE:
2579 if(!card->u.c.slarp_timer) {
2580 if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2581 if_data2->sin_addr.s_addr = remote_IP_addr;
2582 if_data2->sin_family = AF_INET;
2583 err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2584 } else {
2585 if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
2586 if_data1->sin_addr.s_addr = local_IP_addr;
2587 if_data1->sin_family = AF_INET;
2588 if(!(err = devinet_ioctl(SIOCSIFADDR, &if_info))){
2589 if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2590 if_data2->sin_addr.s_addr = remote_IP_addr;
2591 if_data2->sin_family = AF_INET;
2592 err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2596 if(err) {
2597 printk(KERN_INFO "%s: Add route %u.%u.%u.%u failed (%d)\n",
2598 card->devname, NIPQUAD(remote_IP_addr), err);
2599 } else {
2600 ((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED;
2601 printk(KERN_INFO "%s: Dynamic route added.\n",
2602 card->devname);
2603 printk(KERN_INFO "%s: Local IP addr : %u.%u.%u.%u\n",
2604 card->devname, NIPQUAD(local_IP_addr));
2605 printk(KERN_INFO "%s: Remote IP addr: %u.%u.%u.%u\n",
2606 card->devname, NIPQUAD(remote_IP_addr));
2607 chdlc_priv_area->route_removed = 0;
2609 break;
2612 case REMOVE_ROUTE:
2614 /* Change the local ip address of the interface to 0.
2615 * This will also delete the destination route.
2617 if(!card->u.c.slarp_timer) {
2618 if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2619 if_data2->sin_addr.s_addr = 0;
2620 if_data2->sin_family = AF_INET;
2621 err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2622 } else {
2623 if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
2624 if_data1->sin_addr.s_addr = 0;
2625 if_data1->sin_family = AF_INET;
2626 err = devinet_ioctl(SIOCSIFADDR,&if_info);
2629 if(err) {
2630 printk(KERN_INFO
2631 "%s: Remove route %u.%u.%u.%u failed, (err %d)\n",
2632 card->devname, NIPQUAD(remote_IP_addr),
2633 err);
2634 } else {
2635 ((chdlc_private_area_t *)dev->priv)->route_status =
2636 NO_ROUTE;
2637 printk(KERN_INFO "%s: Dynamic route removed: %u.%u.%u.%u\n",
2638 card->devname, NIPQUAD(local_IP_addr));
2639 chdlc_priv_area->route_removed = 1;
2641 break;
2644 set_fs(fs); /* Restore file system */
2649 /*=============================================================================
2650 * Store a UDP management packet for later processing.
2653 static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
2654 struct sk_buff *skb, struct net_device* dev,
2655 chdlc_private_area_t* chdlc_priv_area)
2657 int udp_pkt_stored = 0;
2659 if(!chdlc_priv_area->udp_pkt_lgth &&
2660 (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
2661 chdlc_priv_area->udp_pkt_lgth = skb->len;
2662 chdlc_priv_area->udp_pkt_src = udp_pkt_src;
2663 memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
2664 chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
2665 udp_pkt_stored = 1;
2668 if(udp_pkt_src == UDP_PKT_FRM_STACK){
2669 dev_kfree_skb_any(skb);
2670 }else{
2671 dev_kfree_skb_any(skb);
2674 return(udp_pkt_stored);
2678 /*=============================================================================
2679 * Process UDP management packet.
2682 static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
2683 chdlc_private_area_t* chdlc_priv_area )
2685 unsigned char *buf;
2686 unsigned int frames, len;
2687 struct sk_buff *new_skb;
2688 unsigned short buffer_length, real_len;
2689 unsigned long data_ptr;
2690 unsigned data_length;
2691 int udp_mgmt_req_valid = 1;
2692 CHDLC_MAILBOX_STRUCT *mb = card->mbox;
2693 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
2694 chdlc_udp_pkt_t *chdlc_udp_pkt;
2695 struct timeval tv;
2696 int err;
2697 char ut_char;
2699 chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
2701 if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
2703 /* Only these commands are support for remote debugging.
2704 * All others are not */
2705 switch(chdlc_udp_pkt->cblock.command) {
2707 case READ_GLOBAL_STATISTICS:
2708 case READ_MODEM_STATUS:
2709 case READ_CHDLC_LINK_STATUS:
2710 case CPIPE_ROUTER_UP_TIME:
2711 case READ_COMMS_ERROR_STATS:
2712 case READ_CHDLC_OPERATIONAL_STATS:
2714 /* These two commands are executed for
2715 * each request */
2716 case READ_CHDLC_CONFIGURATION:
2717 case READ_CHDLC_CODE_VERSION:
2718 udp_mgmt_req_valid = 1;
2719 break;
2720 default:
2721 udp_mgmt_req_valid = 0;
2722 break;
2726 if(!udp_mgmt_req_valid) {
2728 /* set length to 0 */
2729 chdlc_udp_pkt->cblock.buffer_length = 0;
2731 /* set return code */
2732 chdlc_udp_pkt->cblock.return_code = 0xCD;
2734 if (net_ratelimit()){
2735 printk(KERN_INFO
2736 "%s: Warning, Illegal UDP command attempted from network: %x\n",
2737 card->devname,chdlc_udp_pkt->cblock.command);
2740 } else {
2741 unsigned long trace_status_cfg_addr = 0;
2742 TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
2743 TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
2745 switch(chdlc_udp_pkt->cblock.command) {
2747 case CPIPE_ENABLE_TRACING:
2748 if (!chdlc_priv_area->TracingEnabled) {
2750 /* OPERATE_DATALINE_MONITOR */
2752 mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
2753 mb->command = SET_TRACE_CONFIGURATION;
2755 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
2756 trace_config = TRACE_ACTIVE;
2757 /* Trace delay mode is not used because it slows
2758 down transfer and results in a standoff situation
2759 when there is a lot of data */
2761 /* Configure the Trace based on user inputs */
2762 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |=
2763 chdlc_udp_pkt->data[0];
2765 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
2766 trace_deactivation_timer = 4000;
2769 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2770 if (err != COMMAND_OK) {
2771 chdlc_error(card,err,mb);
2772 card->TracingEnabled = 0;
2773 chdlc_udp_pkt->cblock.return_code = err;
2774 mb->buffer_length = 0;
2775 break;
2778 /* Get the base address of the trace element list */
2779 mb->buffer_length = 0;
2780 mb->command = READ_TRACE_CONFIGURATION;
2781 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2783 if (err != COMMAND_OK) {
2784 chdlc_error(card,err,mb);
2785 chdlc_priv_area->TracingEnabled = 0;
2786 chdlc_udp_pkt->cblock.return_code = err;
2787 mb->buffer_length = 0;
2788 break;
2791 trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
2792 mb->data) -> ptr_trace_stat_el_cfg_struct;
2794 sdla_peek(&card->hw, trace_status_cfg_addr,
2795 &trace_cfg_struct, sizeof(trace_cfg_struct));
2797 chdlc_priv_area->start_trace_addr = trace_cfg_struct.
2798 base_addr_trace_status_elements;
2800 chdlc_priv_area->number_trace_elements =
2801 trace_cfg_struct.number_trace_status_elements;
2803 chdlc_priv_area->end_trace_addr = (unsigned long)
2804 ((TRACE_STATUS_ELEMENT_STRUCT *)
2805 chdlc_priv_area->start_trace_addr +
2806 (chdlc_priv_area->number_trace_elements - 1));
2808 chdlc_priv_area->base_addr_trace_buffer =
2809 trace_cfg_struct.base_addr_trace_buffer;
2811 chdlc_priv_area->end_addr_trace_buffer =
2812 trace_cfg_struct.end_addr_trace_buffer;
2814 chdlc_priv_area->curr_trace_addr =
2815 trace_cfg_struct.next_trace_element_to_use;
2817 chdlc_priv_area->available_buffer_space = 2000 -
2818 sizeof(ip_pkt_t) -
2819 sizeof(udp_pkt_t) -
2820 sizeof(wp_mgmt_t) -
2821 sizeof(cblock_t) -
2822 sizeof(trace_info_t);
2824 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2825 mb->buffer_length = 0;
2826 chdlc_priv_area->TracingEnabled = 1;
2827 break;
2830 case CPIPE_DISABLE_TRACING:
2831 if (chdlc_priv_area->TracingEnabled) {
2833 /* OPERATE_DATALINE_MONITOR */
2834 mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
2835 mb->command = SET_TRACE_CONFIGURATION;
2836 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
2837 trace_config = TRACE_INACTIVE;
2838 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2841 chdlc_priv_area->TracingEnabled = 0;
2842 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2843 mb->buffer_length = 0;
2844 break;
2847 case CPIPE_GET_TRACE_INFO:
2849 if (!chdlc_priv_area->TracingEnabled) {
2850 chdlc_udp_pkt->cblock.return_code = 1;
2851 mb->buffer_length = 0;
2852 break;
2855 chdlc_udp_pkt->trace_info.ismoredata = 0x00;
2856 buffer_length = 0; /* offset of packet already occupied */
2858 for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
2860 trace_pkt_t *trace_pkt = (trace_pkt_t *)
2861 &chdlc_udp_pkt->data[buffer_length];
2863 sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
2864 (unsigned char *)&trace_element_struct,
2865 sizeof(TRACE_STATUS_ELEMENT_STRUCT));
2867 if (trace_element_struct.opp_flag == 0x00) {
2868 break;
2871 /* get pointer to real data */
2872 data_ptr = trace_element_struct.ptr_data_bfr;
2874 /* See if there is actual data on the trace buffer */
2875 if (data_ptr){
2876 data_length = trace_element_struct.trace_length;
2877 }else{
2878 data_length = 0;
2879 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2882 if( (chdlc_priv_area->available_buffer_space - buffer_length)
2883 < ( sizeof(trace_pkt_t) + data_length) ) {
2885 /* indicate there are more frames on board & exit */
2886 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2887 break;
2890 trace_pkt->status = trace_element_struct.trace_type;
2892 trace_pkt->time_stamp =
2893 trace_element_struct.trace_time_stamp;
2895 trace_pkt->real_length =
2896 trace_element_struct.trace_length;
2898 /* see if we can fit the frame into the user buffer */
2899 real_len = trace_pkt->real_length;
2901 if (data_ptr == 0) {
2902 trace_pkt->data_avail = 0x00;
2903 } else {
2904 unsigned tmp = 0;
2906 /* get the data from circular buffer
2907 must check for end of buffer */
2908 trace_pkt->data_avail = 0x01;
2910 if ((data_ptr + real_len) >
2911 chdlc_priv_area->end_addr_trace_buffer + 1){
2913 tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
2914 sdla_peek(&card->hw, data_ptr,
2915 trace_pkt->data,tmp);
2916 data_ptr = chdlc_priv_area->base_addr_trace_buffer;
2919 sdla_peek(&card->hw, data_ptr,
2920 &trace_pkt->data[tmp], real_len - tmp);
2923 /* zero the opp flag to show we got the frame */
2924 ut_char = 0x00;
2925 sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
2927 /* now move onto the next frame */
2928 chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
2930 /* check if we went over the last address */
2931 if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
2932 chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
2935 if(trace_pkt->data_avail == 0x01) {
2936 buffer_length += real_len - 1;
2939 /* for the header */
2940 buffer_length += sizeof(trace_pkt_t);
2942 } /* For Loop */
2944 if (frames == chdlc_priv_area->number_trace_elements){
2945 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2947 chdlc_udp_pkt->trace_info.num_frames = frames;
2949 mb->buffer_length = buffer_length;
2950 chdlc_udp_pkt->cblock.buffer_length = buffer_length;
2952 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2954 break;
2957 case CPIPE_FT1_READ_STATUS:
2958 ((unsigned char *)chdlc_udp_pkt->data )[0] =
2959 flags->FT1_info_struct.parallel_port_A_input;
2961 ((unsigned char *)chdlc_udp_pkt->data )[1] =
2962 flags->FT1_info_struct.parallel_port_B_input;
2964 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2965 chdlc_udp_pkt->cblock.buffer_length = 2;
2966 mb->buffer_length = 2;
2967 break;
2969 case CPIPE_ROUTER_UP_TIME:
2970 do_gettimeofday( &tv );
2971 chdlc_priv_area->router_up_time = tv.tv_sec -
2972 chdlc_priv_area->router_start_time;
2973 *(unsigned long *)&chdlc_udp_pkt->data =
2974 chdlc_priv_area->router_up_time;
2975 mb->buffer_length = sizeof(unsigned long);
2976 chdlc_udp_pkt->cblock.buffer_length = sizeof(unsigned long);
2977 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2978 break;
2980 case FT1_MONITOR_STATUS_CTRL:
2981 /* Enable FT1 MONITOR STATUS */
2982 if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||
2983 (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
2985 if( rCount++ != 0 ) {
2986 chdlc_udp_pkt->cblock.
2987 return_code = COMMAND_OK;
2988 mb->buffer_length = 1;
2989 break;
2993 /* Disable FT1 MONITOR STATUS */
2994 if( chdlc_udp_pkt->data[0] == 0) {
2996 if( --rCount != 0) {
2997 chdlc_udp_pkt->cblock.
2998 return_code = COMMAND_OK;
2999 mb->buffer_length = 1;
3000 break;
3003 goto dflt_1;
3005 default:
3006 dflt_1:
3007 /* it's a board command */
3008 mb->command = chdlc_udp_pkt->cblock.command;
3009 mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
3010 if (mb->buffer_length) {
3011 memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
3012 data, mb->buffer_length);
3014 /* run the command on the board */
3015 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
3016 if (err != COMMAND_OK) {
3017 break;
3020 /* copy the result back to our buffer */
3021 memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t));
3023 if (mb->buffer_length) {
3024 memcpy(&chdlc_udp_pkt->data, &mb->data,
3025 mb->buffer_length);
3028 } /* end of switch */
3029 } /* end of else */
3031 /* Fill UDP TTL */
3032 chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
3034 len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
3037 if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
3039 /* Must check if we interrupted if_send() routine. The
3040 * tx buffers might be used. If so drop the packet */
3041 if (!test_bit(SEND_CRIT,&card->wandev.critical)) {
3043 if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
3044 ++ card->wandev.stats.tx_packets;
3045 card->wandev.stats.tx_bytes += len;
3048 } else {
3050 /* Pass it up the stack
3051 Allocate socket buffer */
3052 if ((new_skb = dev_alloc_skb(len)) != NULL) {
3053 /* copy data into new_skb */
3055 buf = skb_put(new_skb, len);
3056 memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
3058 /* Decapsulate pkt and pass it up the protocol stack */
3059 new_skb->protocol = htons(ETH_P_IP);
3060 new_skb->dev = dev;
3061 new_skb->mac.raw = new_skb->data;
3063 netif_rx(new_skb);
3064 dev->last_rx = jiffies;
3065 } else {
3067 printk(KERN_INFO "%s: no socket buffers available!\n",
3068 card->devname);
3072 chdlc_priv_area->udp_pkt_lgth = 0;
3074 return 0;
3077 /*============================================================================
3078 * Initialize Receive and Transmit Buffers.
3081 static void init_chdlc_tx_rx_buff( sdla_t* card)
3083 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
3084 CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
3085 CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
3086 char err;
3088 mb->buffer_length = 0;
3089 mb->command = READ_CHDLC_CONFIGURATION;
3090 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
3092 if(err != COMMAND_OK) {
3093 if (card->wandev.dev){
3094 chdlc_error(card,err,mb);
3096 return;
3099 if(card->hw.type == SDLA_S514) {
3100 tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
3101 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
3102 ptr_CHDLC_Tx_stat_el_cfg_struct));
3103 rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
3104 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
3105 ptr_CHDLC_Rx_stat_el_cfg_struct));
3107 /* Setup Head and Tails for buffers */
3108 card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
3109 tx_config->base_addr_Tx_status_elements);
3110 card->u.c.txbuf_last =
3111 (CHDLC_DATA_TX_STATUS_EL_STRUCT *)
3112 card->u.c.txbuf_base +
3113 (tx_config->number_Tx_status_elements - 1);
3115 card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
3116 rx_config->base_addr_Rx_status_elements);
3117 card->u.c.rxbuf_last =
3118 (CHDLC_DATA_RX_STATUS_EL_STRUCT *)
3119 card->u.c.rxbuf_base +
3120 (rx_config->number_Rx_status_elements - 1);
3122 /* Set up next pointer to be used */
3123 card->u.c.txbuf = (void *)(card->hw.dpmbase +
3124 tx_config->next_Tx_status_element_to_use);
3125 card->u.c.rxmb = (void *)(card->hw.dpmbase +
3126 rx_config->next_Rx_status_element_to_use);
3128 else {
3129 tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
3130 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
3131 ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
3133 rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
3134 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
3135 ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
3137 /* Setup Head and Tails for buffers */
3138 card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
3139 (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
3140 card->u.c.txbuf_last =
3141 (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
3142 + (tx_config->number_Tx_status_elements - 1);
3143 card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
3144 (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
3145 card->u.c.rxbuf_last =
3146 (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
3147 + (rx_config->number_Rx_status_elements - 1);
3149 /* Set up next pointer to be used */
3150 card->u.c.txbuf = (void *)(card->hw.dpmbase +
3151 (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
3152 card->u.c.rxmb = (void *)(card->hw.dpmbase +
3153 (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
3156 /* Setup Actual Buffer Start and end addresses */
3157 card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
3158 card->u.c.rx_top = rx_config->end_addr_Rx_buffer;
3162 /*=============================================================================
3163 * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
3164 * _TEST_COUNTER times.
3166 static int intr_test( sdla_t* card)
3168 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
3169 int err,i;
3171 Intr_test_counter = 0;
3173 err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
3175 if (err == CMD_OK) {
3176 for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {
3177 mb->buffer_length = 0;
3178 mb->command = READ_CHDLC_CODE_VERSION;
3179 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
3180 if (err != CMD_OK)
3181 chdlc_error(card, err, mb);
3184 else {
3185 return err;
3188 err = chdlc_set_intr_mode(card, 0);
3190 if (err != CMD_OK)
3191 return err;
3193 return 0;
3196 /*==============================================================================
3197 * Determine what type of UDP call it is. CPIPEAB ?
3199 static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
3201 chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
3203 #ifdef _WAN_UDP_DEBUG
3204 printk(KERN_INFO "SIG %s = %s\n\
3205 UPP %x = %x\n\
3206 PRT %x = %x\n\
3207 REQ %i = %i\n\
3208 36 th = %x 37th = %x\n",
3209 chdlc_udp_pkt->wp_mgmt.signature,
3210 UDPMGMT_SIGNATURE,
3211 chdlc_udp_pkt->udp_pkt.udp_dst_port,
3212 ntohs(card->wandev.udp_port),
3213 chdlc_udp_pkt->ip_pkt.protocol,
3214 UDPMGMT_UDP_PROTOCOL,
3215 chdlc_udp_pkt->wp_mgmt.request_reply,
3216 UDPMGMT_REQUEST,
3217 skb->data[36], skb->data[37]);
3218 #endif
3220 if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
3221 (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
3222 (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
3223 (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
3225 return UDP_CPIPE_TYPE;
3227 }else{
3228 return UDP_INVALID_TYPE;
3232 /*============================================================================
3233 * Set PORT state.
3235 static void port_set_state (sdla_t *card, int state)
3237 if (card->u.c.state != state)
3239 switch (state)
3241 case WAN_CONNECTED:
3242 printk (KERN_INFO "%s: Link connected!\n",
3243 card->devname);
3244 break;
3246 case WAN_CONNECTING:
3247 printk (KERN_INFO "%s: Link connecting...\n",
3248 card->devname);
3249 break;
3251 case WAN_DISCONNECTED:
3252 printk (KERN_INFO "%s: Link disconnected!\n",
3253 card->devname);
3254 break;
3257 card->wandev.state = card->u.c.state = state;
3258 if (card->wandev.dev){
3259 struct net_device *dev = card->wandev.dev;
3260 chdlc_private_area_t *chdlc_priv_area = dev->priv;
3261 chdlc_priv_area->common.state = state;
3266 /*===========================================================================
3267 * config_chdlc
3269 * Configure the chdlc protocol and enable communications.
3271 * The if_open() function binds this function to the poll routine.
3272 * Therefore, this function will run every time the chdlc interface
3273 * is brought up. We cannot run this function from the if_open
3274 * because if_open does not have access to the remote IP address.
3276 * If the communications are not enabled, proceed to configure
3277 * the card and enable communications.
3279 * If the communications are enabled, it means that the interface
3280 * was shutdown by ether the user or driver. In this case, we
3281 * have to check that the IP addresses have not changed. If
3282 * the IP addresses have changed, we have to reconfigure the firmware
3283 * and update the changed IP addresses. Otherwise, just exit.
3287 static int config_chdlc (sdla_t *card)
3289 struct net_device *dev = card->wandev.dev;
3290 chdlc_private_area_t *chdlc_priv_area = dev->priv;
3291 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
3293 if (card->u.c.comm_enabled){
3295 /* Jun 20. 2000: NC
3296 * IP addresses are not used in the API mode */
3298 if ((chdlc_priv_area->ip_local_tmp != chdlc_priv_area->ip_local ||
3299 chdlc_priv_area->ip_remote_tmp != chdlc_priv_area->ip_remote) &&
3300 card->u.c.usedby == WANPIPE) {
3302 /* The IP addersses have changed, we must
3303 * stop the communications and reconfigure
3304 * the card. Reason: the firmware must know
3305 * the local and remote IP addresses. */
3306 disable_comm(card);
3307 port_set_state(card, WAN_DISCONNECTED);
3308 printk(KERN_INFO
3309 "%s: IP addresses changed!\n",
3310 card->devname);
3311 printk(KERN_INFO
3312 "%s: Restarting communications ...\n",
3313 card->devname);
3314 }else{
3315 /* IP addresses are the same and the link is up,
3316 * we don't have to do anything here. Therefore, exit */
3317 return 0;
3321 chdlc_priv_area->ip_local = chdlc_priv_area->ip_local_tmp;
3322 chdlc_priv_area->ip_remote = chdlc_priv_area->ip_remote_tmp;
3325 /* Setup the Board for asynchronous mode */
3326 if (card->u.c.async_mode){
3328 if (set_asy_config(card)) {
3329 printk (KERN_INFO "%s: Failed CHDLC Async configuration!\n",
3330 card->devname);
3331 return 0;
3333 }else{
3334 /* Setup the Board for CHDLC */
3335 if (set_chdlc_config(card)) {
3336 printk (KERN_INFO "%s: Failed CHDLC configuration!\n",
3337 card->devname);
3338 return 0;
3342 /* Set interrupt mode and mask */
3343 if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
3344 APP_INT_ON_GLOBAL_EXCEP_COND |
3345 APP_INT_ON_TX_FRAME |
3346 APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
3347 printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
3348 card->devname);
3349 return 0;
3353 /* Mask the Transmit and Timer interrupt */
3354 flags->interrupt_info_struct.interrupt_permission &=
3355 ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
3357 /* In TTY mode, receive interrupt will be enabled during
3358 * wanpipe_tty_open() operation */
3359 if (card->tty_opt){
3360 flags->interrupt_info_struct.interrupt_permission &= ~APP_INT_ON_RX_FRAME;
3363 /* Enable communications */
3364 if (card->u.c.async_mode){
3365 if (asy_comm_enable(card) != 0) {
3366 printk(KERN_INFO "%s: Failed to enable async commnunication!\n",
3367 card->devname);
3368 flags->interrupt_info_struct.interrupt_permission = 0;
3369 card->u.c.comm_enabled=0;
3370 chdlc_set_intr_mode(card,0);
3371 return 0;
3373 }else{
3374 if (chdlc_comm_enable(card) != 0) {
3375 printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
3376 card->devname);
3377 flags->interrupt_info_struct.interrupt_permission = 0;
3378 card->u.c.comm_enabled=0;
3379 chdlc_set_intr_mode(card,0);
3380 return 0;
3384 /* Initialize Rx/Tx buffer control fields */
3385 init_chdlc_tx_rx_buff(card);
3386 port_set_state(card, WAN_CONNECTING);
3387 return 0;
3391 /*============================================================
3392 * chdlc_poll
3394 * Rationale:
3395 * We cannot manipulate the routing tables, or
3396 * ip addresses withing the interrupt. Therefore
3397 * we must perform such actons outside an interrupt
3398 * at a later time.
3400 * Description:
3401 * CHDLC polling routine, responsible for
3402 * shutting down interfaces upon disconnect
3403 * and adding/removing routes.
3405 * Usage:
3406 * This function is executed for each CHDLC
3407 * interface through a tq_schedule bottom half.
3409 * trigger_chdlc_poll() function is used to kick
3410 * the chldc_poll routine.
3413 static void chdlc_poll(struct net_device *dev)
3415 chdlc_private_area_t *chdlc_priv_area;
3416 sdla_t *card;
3417 u8 check_gateway=0;
3418 SHARED_MEMORY_INFO_STRUCT* flags;
3421 if (!dev || (chdlc_priv_area=dev->priv) == NULL)
3422 return;
3424 card = chdlc_priv_area->card;
3425 flags = card->u.c.flags;
3427 /* (Re)Configuraiton is in progress, stop what you are
3428 * doing and get out */
3429 if (test_bit(PERI_CRIT,&card->wandev.critical)){
3430 clear_bit(POLL_CRIT,&card->wandev.critical);
3431 return;
3434 /* if_open() function has triggered the polling routine
3435 * to determine the configured IP addresses. Once the
3436 * addresses are found, trigger the chdlc configuration */
3437 if (test_bit(0,&chdlc_priv_area->config_chdlc)){
3439 chdlc_priv_area->ip_local_tmp = get_ip_address(dev,WAN_LOCAL_IP);
3440 chdlc_priv_area->ip_remote_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP);
3442 /* Jun 20. 2000 Bug Fix
3443 * Only perform this check in WANPIPE mode, since
3444 * IP addresses are not used in the API mode. */
3446 if (chdlc_priv_area->ip_local_tmp == chdlc_priv_area->ip_remote_tmp &&
3447 card->u.c.slarp_timer == 0x00 &&
3448 !card->u.c.backup &&
3449 card->u.c.usedby == WANPIPE){
3451 if (++chdlc_priv_area->ip_error > MAX_IP_ERRORS){
3452 printk(KERN_INFO "\n%s: --- WARNING ---\n",
3453 card->devname);
3454 printk(KERN_INFO
3455 "%s: The local IP address is the same as the\n",
3456 card->devname);
3457 printk(KERN_INFO
3458 "%s: Point-to-Point IP address.\n",
3459 card->devname);
3460 printk(KERN_INFO "%s: --- WARNING ---\n\n",
3461 card->devname);
3462 }else{
3463 clear_bit(POLL_CRIT,&card->wandev.critical);
3464 chdlc_priv_area->poll_delay_timer.expires = jiffies+HZ;
3465 add_timer(&chdlc_priv_area->poll_delay_timer);
3466 return;
3470 clear_bit(0,&chdlc_priv_area->config_chdlc);
3471 clear_bit(POLL_CRIT,&card->wandev.critical);
3473 chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
3474 flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
3475 return;
3477 /* Dynamic interface implementation, as well as dynamic
3478 * routing. */
3480 switch (card->u.c.state){
3482 case WAN_DISCONNECTED:
3484 /* If the dynamic interface configuration is on, and interface
3485 * is up, then bring down the netowrk interface */
3487 if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) &&
3488 !test_bit(DEV_DOWN, &chdlc_priv_area->interface_down) &&
3489 card->wandev.dev->flags & IFF_UP){
3491 printk(KERN_INFO "%s: Interface %s down.\n",
3492 card->devname,card->wandev.dev->name);
3493 change_dev_flags(card->wandev.dev,(card->wandev.dev->flags&~IFF_UP));
3494 set_bit(DEV_DOWN,&chdlc_priv_area->interface_down);
3495 chdlc_priv_area->route_status = NO_ROUTE;
3497 }else{
3498 /* We need to check if the local IP address is
3499 * zero. If it is, we shouldn't try to remove it.
3502 if (card->wandev.dev->flags & IFF_UP &&
3503 get_ip_address(card->wandev.dev,WAN_LOCAL_IP) &&
3504 chdlc_priv_area->route_status != NO_ROUTE &&
3505 card->u.c.slarp_timer){
3507 process_route(card);
3510 break;
3512 case WAN_CONNECTED:
3514 /* In SMP machine this code can execute before the interface
3515 * comes up. In this case, we must make sure that we do not
3516 * try to bring up the interface before dev_open() is finished */
3519 /* DEV_DOWN will be set only when we bring down the interface
3520 * for the very first time. This way we know that it was us
3521 * that brought the interface down */
3523 if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) &&
3524 test_bit(DEV_DOWN, &chdlc_priv_area->interface_down) &&
3525 !(card->wandev.dev->flags & IFF_UP)){
3527 printk(KERN_INFO "%s: Interface %s up.\n",
3528 card->devname,card->wandev.dev->name);
3529 change_dev_flags(card->wandev.dev,(card->wandev.dev->flags|IFF_UP));
3530 clear_bit(DEV_DOWN,&chdlc_priv_area->interface_down);
3531 check_gateway=1;
3534 if (chdlc_priv_area->route_status == ADD_ROUTE &&
3535 card->u.c.slarp_timer){
3537 process_route(card);
3538 check_gateway=1;
3541 if (chdlc_priv_area->gateway && check_gateway)
3542 add_gateway(card,dev);
3544 break;
3547 clear_bit(POLL_CRIT,&card->wandev.critical);
3550 /*============================================================
3551 * trigger_chdlc_poll
3553 * Description:
3554 * Add a chdlc_poll() work entry into the keventd work queue
3555 * for a specific dlci/interface. This will kick
3556 * the fr_poll() routine at a later time.
3558 * Usage:
3559 * Interrupts use this to defer a taks to
3560 * a polling routine.
3563 static void trigger_chdlc_poll(struct net_device *dev)
3565 chdlc_private_area_t *chdlc_priv_area;
3566 sdla_t *card;
3568 if (!dev)
3569 return;
3571 if ((chdlc_priv_area = dev->priv)==NULL)
3572 return;
3574 card = chdlc_priv_area->card;
3576 if (test_and_set_bit(POLL_CRIT,&card->wandev.critical)){
3577 return;
3579 if (test_bit(PERI_CRIT,&card->wandev.critical)){
3580 return;
3582 schedule_work(&chdlc_priv_area->poll_work);
3586 static void chdlc_poll_delay (unsigned long dev_ptr)
3588 struct net_device *dev = (struct net_device *)dev_ptr;
3589 trigger_chdlc_poll(dev);
3593 void s508_lock (sdla_t *card, unsigned long *smp_flags)
3595 spin_lock_irqsave(&card->wandev.lock, *smp_flags);
3596 if (card->next){
3597 spin_lock(&card->next->wandev.lock);
3601 void s508_unlock (sdla_t *card, unsigned long *smp_flags)
3603 if (card->next){
3604 spin_unlock(&card->next->wandev.lock);
3606 spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
3609 //*********** TTY SECTION ****************
3611 static void wanpipe_tty_trigger_tx_irq(sdla_t *card)
3613 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
3614 INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
3615 chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
3618 static void wanpipe_tty_trigger_poll(sdla_t *card)
3620 schedule_work(&card->tty_work);
3623 static void tty_poll_work (void* data)
3625 sdla_t *card = (sdla_t*)data;
3626 struct tty_struct *tty;
3628 if ((tty=card->tty)==NULL)
3629 return;
3631 tty_wakeup(tty);
3632 #if defined(SERIAL_HAVE_POLL_WAIT)
3633 wake_up_interruptible(&tty->poll_wait);
3634 #endif
3635 return;
3638 static void wanpipe_tty_close(struct tty_struct *tty, struct file * filp)
3640 sdla_t *card;
3641 unsigned long smp_flags;
3643 if (!tty || !tty->driver_data){
3644 return;
3647 card = (sdla_t*)tty->driver_data;
3649 if (!card)
3650 return;
3652 printk(KERN_INFO "%s: Closing TTY Driver!\n",
3653 card->devname);
3655 /* Sanity Check */
3656 if (!card->tty_open)
3657 return;
3659 wanpipe_close(card);
3660 if (--card->tty_open == 0){
3662 lock_adapter_irq(&card->wandev.lock,&smp_flags);
3663 card->tty=NULL;
3664 chdlc_disable_comm_shutdown(card);
3665 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
3667 kfree(card->tty_buf);
3668 card->tty_buf = NULL;
3669 kfree(card->tty_rx);
3670 card->tty_rx = NULL;
3672 return;
3674 static int wanpipe_tty_open(struct tty_struct *tty, struct file * filp)
3676 unsigned long smp_flags;
3677 sdla_t *card;
3679 if (!tty){
3680 return -ENODEV;
3683 if (!tty->driver_data){
3684 int port;
3685 port = tty->index;
3686 if ((port < 0) || (port >= NR_PORTS))
3687 return -ENODEV;
3689 tty->driver_data = WAN_CARD(port);
3690 if (!tty->driver_data)
3691 return -ENODEV;
3694 card = (sdla_t*)tty->driver_data;
3696 if (!card){
3697 lock_adapter_irq(&card->wandev.lock,&smp_flags);
3698 card->tty=NULL;
3699 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
3700 return -ENODEV;
3703 printk(KERN_INFO "%s: Opening TTY Driver!\n",
3704 card->devname);
3706 if (card->tty_open == 0){
3707 lock_adapter_irq(&card->wandev.lock,&smp_flags);
3708 card->tty=tty;
3709 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
3711 if (!card->tty_buf){
3712 card->tty_buf = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL);
3713 if (!card->tty_buf){
3714 card->tty_buf=NULL;
3715 card->tty=NULL;
3716 return -ENOMEM;
3720 if (!card->tty_rx){
3721 card->tty_rx = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL);
3722 if (!card->tty_rx){
3723 /* Free the buffer above */
3724 kfree(card->tty_buf);
3725 card->tty_buf=NULL;
3726 card->tty=NULL;
3727 return -ENOMEM;
3732 ++card->tty_open;
3733 wanpipe_open(card);
3734 return 0;
3737 static int wanpipe_tty_write(struct tty_struct * tty, const unsigned char *buf, int count)
3739 unsigned long smp_flags=0;
3740 sdla_t *card=NULL;
3742 if (!tty){
3743 dbg_printk(KERN_INFO "NO TTY in Write\n");
3744 return -ENODEV;
3747 card = (sdla_t *)tty->driver_data;
3749 if (!card){
3750 dbg_printk(KERN_INFO "No Card in TTY Write\n");
3751 return -ENODEV;
3754 if (count > card->wandev.mtu){
3755 dbg_printk(KERN_INFO "Frame too big in Write %i Max: %i\n",
3756 count,card->wandev.mtu);
3757 return -EINVAL;
3760 if (card->wandev.state != WAN_CONNECTED){
3761 dbg_printk(KERN_INFO "Card not connected in TTY Write\n");
3762 return -EINVAL;
3765 /* Lock the 508 Card: SMP is supported */
3766 if(card->hw.type != SDLA_S514){
3767 s508_lock(card,&smp_flags);
3770 if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){
3771 printk(KERN_INFO "%s: Critical in TTY Write\n",
3772 card->devname);
3774 /* Lock the 508 Card: SMP is supported */
3775 if(card->hw.type != SDLA_S514)
3776 s508_unlock(card,&smp_flags);
3778 return -EINVAL;
3781 if (chdlc_send(card,(void*)buf,count)){
3782 dbg_printk(KERN_INFO "%s: Failed to send, retry later: kernel!\n",
3783 card->devname);
3784 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
3786 wanpipe_tty_trigger_tx_irq(card);
3788 if(card->hw.type != SDLA_S514)
3789 s508_unlock(card,&smp_flags);
3790 return 0;
3792 dbg_printk(KERN_INFO "%s: Packet sent OK: %i\n",card->devname,count);
3793 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
3795 if(card->hw.type != SDLA_S514)
3796 s508_unlock(card,&smp_flags);
3798 return count;
3801 static void wanpipe_tty_receive(sdla_t *card, unsigned addr, unsigned int len)
3803 unsigned offset=0;
3804 unsigned olen=len;
3805 char fp=0;
3806 struct tty_struct *tty;
3807 int i;
3808 struct tty_ldisc *ld;
3810 if (!card->tty_open){
3811 dbg_printk(KERN_INFO "%s: TTY not open during receive\n",
3812 card->devname);
3813 return;
3816 if ((tty=card->tty) == NULL){
3817 dbg_printk(KERN_INFO "%s: No TTY on receive\n",
3818 card->devname);
3819 return;
3822 if (!tty->driver_data){
3823 dbg_printk(KERN_INFO "%s: No Driver Data, or Flip on receive\n",
3824 card->devname);
3825 return;
3829 if (card->u.c.async_mode){
3830 if ((tty->flip.count+len) >= TTY_FLIPBUF_SIZE){
3831 if (net_ratelimit()){
3832 printk(KERN_INFO
3833 "%s: Received packet size too big: %i bytes, Max: %i!\n",
3834 card->devname,len,TTY_FLIPBUF_SIZE);
3836 return;
3840 if((addr + len) > card->u.c.rx_top + 1) {
3841 offset = card->u.c.rx_top - addr + 1;
3843 sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, offset);
3845 addr = card->u.c.rx_base;
3846 len -= offset;
3848 tty->flip.char_buf_ptr+=offset;
3849 tty->flip.count+=offset;
3850 for (i=0;i<offset;i++){
3851 *tty->flip.flag_buf_ptr = 0;
3852 tty->flip.flag_buf_ptr++;
3856 sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, len);
3858 tty->flip.char_buf_ptr+=len;
3859 card->tty->flip.count+=len;
3860 for (i=0;i<len;i++){
3861 *tty->flip.flag_buf_ptr = 0;
3862 tty->flip.flag_buf_ptr++;
3865 tty->low_latency=1;
3866 tty_flip_buffer_push(tty);
3867 }else{
3868 if (!card->tty_rx){
3869 if (net_ratelimit()){
3870 printk(KERN_INFO
3871 "%s: Receive sync buffer not available!\n",
3872 card->devname);
3874 return;
3877 if (len > TTY_CHDLC_MAX_MTU){
3878 if (net_ratelimit()){
3879 printk(KERN_INFO
3880 "%s: Received packet size too big: %i bytes, Max: %i!\n",
3881 card->devname,len,TTY_FLIPBUF_SIZE);
3883 return;
3887 if((addr + len) > card->u.c.rx_top + 1) {
3888 offset = card->u.c.rx_top - addr + 1;
3890 sdla_peek(&card->hw, addr, card->tty_rx, offset);
3892 addr = card->u.c.rx_base;
3893 len -= offset;
3895 sdla_peek(&card->hw, addr, card->tty_rx+offset, len);
3896 ld = tty_ldisc_ref(tty);
3897 if (ld) {
3898 if (ld->receive_buf)
3899 ld->receive_buf(tty,card->tty_rx,&fp,olen);
3900 tty_ldisc_deref(ld);
3901 }else{
3902 if (net_ratelimit()){
3903 printk(KERN_INFO
3904 "%s: NO TTY Sync line discipline!\n",
3905 card->devname);
3910 dbg_printk(KERN_INFO "%s: Received Data %i\n",card->devname,olen);
3911 return;
3914 #if 0
3915 static int wanpipe_tty_ioctl(struct tty_struct *tty, struct file * file,
3916 unsigned int cmd, unsigned long arg)
3918 return -ENOIOCTLCMD;
3920 #endif
3922 static void wanpipe_tty_stop(struct tty_struct *tty)
3924 return;
3927 static void wanpipe_tty_start(struct tty_struct *tty)
3929 return;
3932 static int config_tty (sdla_t *card)
3934 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
3936 /* Setup the Board for asynchronous mode */
3937 if (card->u.c.async_mode){
3939 if (set_asy_config(card)) {
3940 printk (KERN_INFO "%s: Failed CHDLC Async configuration!\n",
3941 card->devname);
3942 return -EINVAL;
3944 }else{
3945 /* Setup the Board for CHDLC */
3946 if (set_chdlc_config(card)) {
3947 printk (KERN_INFO "%s: Failed CHDLC configuration!\n",
3948 card->devname);
3949 return -EINVAL;
3953 /* Set interrupt mode and mask */
3954 if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
3955 APP_INT_ON_GLOBAL_EXCEP_COND |
3956 APP_INT_ON_TX_FRAME |
3957 APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
3958 printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
3959 card->devname);
3960 return -EINVAL;
3964 /* Mask the Transmit and Timer interrupt */
3965 flags->interrupt_info_struct.interrupt_permission &=
3966 ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
3969 /* Enable communications */
3970 if (card->u.c.async_mode){
3971 if (asy_comm_enable(card) != 0) {
3972 printk(KERN_INFO "%s: Failed to enable async commnunication!\n",
3973 card->devname);
3974 flags->interrupt_info_struct.interrupt_permission = 0;
3975 card->u.c.comm_enabled=0;
3976 chdlc_set_intr_mode(card,0);
3977 return -EINVAL;
3979 }else{
3980 if (chdlc_comm_enable(card) != 0) {
3981 printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
3982 card->devname);
3983 flags->interrupt_info_struct.interrupt_permission = 0;
3984 card->u.c.comm_enabled=0;
3985 chdlc_set_intr_mode(card,0);
3986 return -EINVAL;
3990 /* Initialize Rx/Tx buffer control fields */
3991 init_chdlc_tx_rx_buff(card);
3992 port_set_state(card, WAN_CONNECTING);
3993 return 0;
3997 static int change_speed(sdla_t *card, struct tty_struct *tty,
3998 struct termios *old_termios)
4000 int baud, ret=0;
4001 unsigned cflag;
4002 int dbits,sbits,parity,handshaking;
4004 cflag = tty->termios->c_cflag;
4006 /* There is always one stop bit */
4007 sbits=WANOPT_ONE;
4009 /* Parity is defaulted to NONE */
4010 parity = WANOPT_NONE;
4012 handshaking=0;
4014 /* byte size and parity */
4015 switch (cflag & CSIZE) {
4016 case CS5: dbits = 5; break;
4017 case CS6: dbits = 6; break;
4018 case CS7: dbits = 7; break;
4019 case CS8: dbits = 8; break;
4020 /* Never happens, but GCC is too dumb to figure it out */
4021 default: dbits = 8; break;
4024 /* One more stop bit should be supported, thus increment
4025 * the number of stop bits Max=2 */
4026 if (cflag & CSTOPB) {
4027 sbits = WANOPT_TWO;
4029 if (cflag & PARENB) {
4030 parity = WANOPT_EVEN;
4032 if (cflag & PARODD){
4033 parity = WANOPT_ODD;
4036 /* Determine divisor based on baud rate */
4037 baud = tty_get_baud_rate(tty);
4039 if (!baud)
4040 baud = 9600; /* B0 transition handled in rs_set_termios */
4042 if (cflag & CRTSCTS) {
4043 handshaking|=ASY_RTS_HS_FOR_RX;
4046 if (I_IGNPAR(tty))
4047 parity = WANOPT_NONE;
4049 if (I_IXOFF(tty)){
4050 handshaking|=ASY_XON_XOFF_HS_FOR_RX;
4051 handshaking|=ASY_XON_XOFF_HS_FOR_TX;
4054 if (I_IXON(tty)){
4055 handshaking|=ASY_XON_XOFF_HS_FOR_RX;
4056 handshaking|=ASY_XON_XOFF_HS_FOR_TX;
4059 if (card->u.c.async_mode){
4060 if (card->wandev.bps != baud)
4061 ret=1;
4062 card->wandev.bps = baud;
4065 if (card->u.c.async_mode){
4066 if (card->u.c.protocol_options != handshaking)
4067 ret=1;
4068 card->u.c.protocol_options = handshaking;
4070 if (card->u.c.tx_bits_per_char != dbits)
4071 ret=1;
4072 card->u.c.tx_bits_per_char = dbits;
4074 if (card->u.c.rx_bits_per_char != dbits)
4075 ret=1;
4076 card->u.c.rx_bits_per_char = dbits;
4078 if (card->u.c.stop_bits != sbits)
4079 ret=1;
4080 card->u.c.stop_bits = sbits;
4082 if (card->u.c.parity != parity)
4083 ret=1;
4084 card->u.c.parity = parity;
4086 card->u.c.break_timer = 50;
4087 card->u.c.inter_char_timer = 10;
4088 card->u.c.rx_complete_length = 100;
4089 card->u.c.xon_char = 0xFE;
4090 }else{
4091 card->u.c.protocol_options = HDLC_STREAMING_MODE;
4094 return ret;
4098 static void wanpipe_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
4100 sdla_t *card;
4101 int err=1;
4103 if (!tty){
4104 return;
4107 card = (sdla_t *)tty->driver_data;
4109 if (!card)
4110 return;
4112 if (change_speed(card, tty, old_termios) || !card->u.c.comm_enabled){
4113 unsigned long smp_flags;
4115 if (card->u.c.comm_enabled){
4116 lock_adapter_irq(&card->wandev.lock,&smp_flags);
4117 chdlc_disable_comm_shutdown(card);
4118 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
4120 lock_adapter_irq(&card->wandev.lock,&smp_flags);
4121 err = config_tty(card);
4122 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
4123 if (card->u.c.async_mode){
4124 printk(KERN_INFO "%s: TTY Async Configuration:\n"
4125 " Baud =%i\n"
4126 " Handshaking =%s\n"
4127 " Tx Dbits =%i\n"
4128 " Rx Dbits =%i\n"
4129 " Parity =%s\n"
4130 " Stop Bits =%i\n",
4131 card->devname,
4132 card->wandev.bps,
4133 opt_decode[card->u.c.protocol_options],
4134 card->u.c.tx_bits_per_char,
4135 card->u.c.rx_bits_per_char,
4136 p_decode[card->u.c.parity] ,
4137 card->u.c.stop_bits);
4138 }else{
4139 printk(KERN_INFO "%s: TTY Sync Configuration:\n"
4140 " Baud =%i\n"
4141 " Protocol =HDLC_STREAMING\n",
4142 card->devname,card->wandev.bps);
4144 if (!err){
4145 port_set_state(card,WAN_CONNECTED);
4146 }else{
4147 port_set_state(card,WAN_DISCONNECTED);
4150 return;
4153 static void wanpipe_tty_put_char(struct tty_struct *tty, unsigned char ch)
4155 sdla_t *card;
4156 unsigned long smp_flags=0;
4158 if (!tty){
4159 return;
4162 card = (sdla_t *)tty->driver_data;
4164 if (!card)
4165 return;
4167 if (card->wandev.state != WAN_CONNECTED)
4168 return;
4170 if(card->hw.type != SDLA_S514)
4171 s508_lock(card,&smp_flags);
4173 if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){
4175 wanpipe_tty_trigger_tx_irq(card);
4177 if(card->hw.type != SDLA_S514)
4178 s508_unlock(card,&smp_flags);
4179 return;
4182 if (chdlc_send(card,(void*)&ch,1)){
4183 wanpipe_tty_trigger_tx_irq(card);
4184 dbg_printk("%s: Failed to TX char!\n",card->devname);
4187 dbg_printk("%s: Char TX OK\n",card->devname);
4189 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
4191 if(card->hw.type != SDLA_S514)
4192 s508_unlock(card,&smp_flags);
4194 return;
4197 static void wanpipe_tty_flush_chars(struct tty_struct *tty)
4199 return;
4202 static void wanpipe_tty_flush_buffer(struct tty_struct *tty)
4204 if (!tty)
4205 return;
4207 #if defined(SERIAL_HAVE_POLL_WAIT)
4208 wake_up_interruptible(&tty->poll_wait);
4209 #endif
4210 tty_wakeup(tty);
4211 return;
4215 * This function is used to send a high-priority XON/XOFF character to
4216 * the device
4218 static void wanpipe_tty_send_xchar(struct tty_struct *tty, char ch)
4220 return;
4224 static int wanpipe_tty_chars_in_buffer(struct tty_struct *tty)
4226 return 0;
4230 static int wanpipe_tty_write_room(struct tty_struct *tty)
4232 sdla_t *card;
4234 printk(KERN_INFO "TTY Write Room\n");
4236 if (!tty){
4237 return 0;
4240 card = (sdla_t *)tty->driver_data;
4241 if (!card)
4242 return 0;
4244 if (card->wandev.state != WAN_CONNECTED)
4245 return 0;
4247 return SEC_MAX_NO_DATA_BYTES_IN_FRAME;
4251 static int set_modem_status(sdla_t *card, unsigned char data)
4253 CHDLC_MAILBOX_STRUCT *mb = card->mbox;
4254 int err;
4256 mb->buffer_length=1;
4257 mb->command=SET_MODEM_STATUS;
4258 mb->data[0]=data;
4259 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
4260 if (err != COMMAND_OK)
4261 chdlc_error (card, err, mb);
4263 return err;
4266 static void wanpipe_tty_hangup(struct tty_struct *tty)
4268 sdla_t *card;
4269 unsigned long smp_flags;
4271 printk(KERN_INFO "TTY Hangup!\n");
4273 if (!tty){
4274 return;
4277 card = (sdla_t *)tty->driver_data;
4278 if (!card)
4279 return;
4281 lock_adapter_irq(&card->wandev.lock,&smp_flags);
4282 set_modem_status(card,0);
4283 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
4284 return;
4287 static void wanpipe_tty_break(struct tty_struct *tty, int break_state)
4289 return;
4292 static void wanpipe_tty_wait_until_sent(struct tty_struct *tty, int timeout)
4294 return;
4297 static void wanpipe_tty_throttle(struct tty_struct * tty)
4299 return;
4302 static void wanpipe_tty_unthrottle(struct tty_struct * tty)
4304 return;
4307 int wanpipe_tty_read_proc(char *page, char **start, off_t off, int count,
4308 int *eof, void *data)
4310 return 0;
4314 * The serial driver boot-time initialization code!
4316 int wanpipe_tty_init(sdla_t *card)
4318 struct serial_state * state;
4320 /* Initialize the tty_driver structure */
4322 if (card->tty_minor < 0 || card->tty_minor > NR_PORTS){
4323 printk(KERN_INFO "%s: Illegal Minor TTY number (0-4): %i\n",
4324 card->devname,card->tty_minor);
4325 return -EINVAL;
4328 if (WAN_CARD(card->tty_minor)){
4329 printk(KERN_INFO "%s: TTY Minor %i, already in use\n",
4330 card->devname,card->tty_minor);
4331 return -EBUSY;
4334 if (tty_init_cnt==0){
4336 printk(KERN_INFO "%s: TTY %s Driver Init: Major %i, Minor Range %i-%i\n",
4337 card->devname,
4338 card->u.c.async_mode ? "ASYNC" : "SYNC",
4339 WAN_TTY_MAJOR,MIN_PORT,MAX_PORT);
4341 tty_driver_mode = card->u.c.async_mode;
4343 memset(&serial_driver, 0, sizeof(struct tty_driver));
4344 serial_driver.magic = TTY_DRIVER_MAGIC;
4345 serial_driver.owner = THIS_MODULE;
4346 serial_driver.driver_name = "wanpipe_tty";
4347 serial_driver.name = "ttyW";
4348 serial_driver.major = WAN_TTY_MAJOR;
4349 serial_driver.minor_start = WAN_TTY_MINOR;
4350 serial_driver.num = NR_PORTS;
4351 serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
4352 serial_driver.subtype = SERIAL_TYPE_NORMAL;
4354 serial_driver.init_termios = tty_std_termios;
4355 serial_driver.init_termios.c_cflag =
4356 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
4357 serial_driver.flags = TTY_DRIVER_REAL_RAW;
4359 serial_driver.refcount = 1; /* !@!@^#^&!! */
4361 serial_driver.open = wanpipe_tty_open;
4362 serial_driver.close = wanpipe_tty_close;
4363 serial_driver.write = wanpipe_tty_write;
4365 serial_driver.put_char = wanpipe_tty_put_char;
4366 serial_driver.flush_chars = wanpipe_tty_flush_chars;
4367 serial_driver.write_room = wanpipe_tty_write_room;
4368 serial_driver.chars_in_buffer = wanpipe_tty_chars_in_buffer;
4369 serial_driver.flush_buffer = wanpipe_tty_flush_buffer;
4370 //serial_driver.ioctl = wanpipe_tty_ioctl;
4371 serial_driver.throttle = wanpipe_tty_throttle;
4372 serial_driver.unthrottle = wanpipe_tty_unthrottle;
4373 serial_driver.send_xchar = wanpipe_tty_send_xchar;
4374 serial_driver.set_termios = wanpipe_tty_set_termios;
4375 serial_driver.stop = wanpipe_tty_stop;
4376 serial_driver.start = wanpipe_tty_start;
4377 serial_driver.hangup = wanpipe_tty_hangup;
4378 serial_driver.break_ctl = wanpipe_tty_break;
4379 serial_driver.wait_until_sent = wanpipe_tty_wait_until_sent;
4380 serial_driver.read_proc = wanpipe_tty_read_proc;
4382 if (tty_register_driver(&serial_driver)){
4383 printk(KERN_INFO "%s: Failed to register serial driver!\n",
4384 card->devname);
4389 /* The subsequent ports must comply to the initial configuration */
4390 if (tty_driver_mode != card->u.c.async_mode){
4391 printk(KERN_INFO "%s: Error: TTY Driver operation mode mismatch!\n",
4392 card->devname);
4393 printk(KERN_INFO "%s: The TTY driver is configured for %s!\n",
4394 card->devname, tty_driver_mode ? "ASYNC" : "SYNC");
4395 return -EINVAL;
4398 tty_init_cnt++;
4400 printk(KERN_INFO "%s: Initializing TTY %s Driver Minor %i\n",
4401 card->devname,
4402 tty_driver_mode ? "ASYNC" : "SYNC",
4403 card->tty_minor);
4405 tty_card_map[card->tty_minor] = card;
4406 state = &rs_table[card->tty_minor];
4408 state->magic = SSTATE_MAGIC;
4409 state->line = 0;
4410 state->type = PORT_UNKNOWN;
4411 state->custom_divisor = 0;
4412 state->close_delay = 5*HZ/10;
4413 state->closing_wait = 30*HZ;
4414 state->icount.cts = state->icount.dsr =
4415 state->icount.rng = state->icount.dcd = 0;
4416 state->icount.rx = state->icount.tx = 0;
4417 state->icount.frame = state->icount.parity = 0;
4418 state->icount.overrun = state->icount.brk = 0;
4419 state->irq = card->wandev.irq;
4421 INIT_WORK(&card->tty_work, tty_poll_work, (void*)card);
4422 return 0;
4426 MODULE_LICENSE("GPL");
4428 /****** End ****************************************************************/