Merge with Linux 2.5.74.
[linux-2.6/linux-mips.git] / drivers / net / wan / sdla_chdlc.c
blob5ca0ef0599b374368b97cdffcf0ebf34093822ae
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/version.h>
53 #include <linux/kernel.h> /* printk(), and other useful stuff */
54 #include <linux/stddef.h> /* offsetof(), etc. */
55 #include <linux/errno.h> /* return codes */
56 #include <linux/string.h> /* inline memset(), etc. */
57 #include <linux/slab.h> /* kmalloc(), kfree() */
58 #include <linux/wanrouter.h> /* WAN router definitions */
59 #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
60 #include <linux/if_arp.h> /* ARPHRD_* defines */
63 #include <asm/uaccess.h>
64 #include <linux/inetdevice.h>
65 #include <linux/netdevice.h>
67 #include <linux/in.h> /* sockaddr_in */
68 #include <linux/inet.h>
69 #include <linux/if.h>
70 #include <asm/byteorder.h> /* htons(), etc. */
71 #include <linux/sdlapci.h>
72 #include <asm/io.h>
74 #include <linux/sdla_chdlc.h> /* CHDLC firmware API definitions */
75 #include <linux/sdla_asy.h> /* CHDLC (async) API definitions */
77 #include <linux/if_wanpipe_common.h> /* Socket Driver common area */
78 #include <linux/if_wanpipe.h>
80 /* TTY Includes */
81 #include <linux/tty.h>
82 #include <linux/tty_flip.h>
83 #include <linux/serial.h>
86 /****** Defines & Macros ****************************************************/
88 /* reasons for enabling the timer interrupt on the adapter */
89 #define TMR_INT_ENABLED_UDP 0x01
90 #define TMR_INT_ENABLED_UPDATE 0x02
91 #define TMR_INT_ENABLED_CONFIG 0x10
93 #define MAX_IP_ERRORS 10
95 #define TTY_CHDLC_MAX_MTU 2000
96 #define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */
97 #define CHDLC_HDR_LEN 1
99 #define CHDLC_API 0x01
101 #define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" )
102 #define MAX_BH_BUFF 10
104 //#define PRINT_DEBUG
105 #ifdef PRINT_DEBUG
106 #define dbg_printk(format, a...) printk(format, ## a)
107 #else
108 #define dbg_printk(format, a...)
109 #endif
111 /******Data Structures*****************************************************/
113 /* This structure is placed in the private data area of the device structure.
114 * The card structure used to occupy the private area but now the following
115 * structure will incorporate the card structure along with CHDLC specific data
118 typedef struct chdlc_private_area
120 wanpipe_common_t common;
121 sdla_t *card;
122 int TracingEnabled; /* For enabling Tracing */
123 unsigned long curr_trace_addr; /* Used for Tracing */
124 unsigned long start_trace_addr;
125 unsigned long end_trace_addr;
126 unsigned long base_addr_trace_buffer;
127 unsigned long end_addr_trace_buffer;
128 unsigned short number_trace_elements;
129 unsigned available_buffer_space;
130 unsigned long router_start_time;
131 unsigned char route_status;
132 unsigned char route_removed;
133 unsigned long tick_counter; /* For 5s timeout counter */
134 unsigned long router_up_time;
135 u32 IP_address; /* IP addressing */
136 u32 IP_netmask;
137 u32 ip_local;
138 u32 ip_remote;
139 u32 ip_local_tmp;
140 u32 ip_remote_tmp;
141 u8 ip_error;
142 u8 config_chdlc;
143 u8 config_chdlc_timeout;
144 unsigned char mc; /* Mulitcast support on/off */
145 unsigned short udp_pkt_lgth; /* udp packet processing */
146 char udp_pkt_src;
147 char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
148 unsigned short timer_int_enabled;
149 char update_comms_stats; /* updating comms stats */
151 bh_data_t *bh_head; /* Circular buffer for chdlc_bh */
152 unsigned long tq_working;
153 volatile int bh_write;
154 volatile int bh_read;
155 atomic_t bh_buff_used;
157 unsigned char interface_down;
159 /* Polling work queue entry. Each interface
160 * has its own work queue entry, which is used
161 * to defer events from the interrupt */
162 struct work_struct poll_work;
163 struct timer_list poll_delay_timer;
165 u8 gateway;
166 u8 true_if_encoding;
167 //FIXME: add driver stats as per frame relay!
169 } chdlc_private_area_t;
171 /* Route Status options */
172 #define NO_ROUTE 0x00
173 #define ADD_ROUTE 0x01
174 #define ROUTE_ADDED 0x02
175 #define REMOVE_ROUTE 0x03
178 /* variable for keeping track of enabling/disabling FT1 monitor status */
179 static int rCount = 0;
181 /* variable for tracking how many interfaces to open for WANPIPE on the
182 two ports */
184 extern void disable_irq(unsigned int);
185 extern void enable_irq(unsigned int);
187 /****** Function Prototypes *************************************************/
188 /* WAN link driver entry points. These are called by the WAN router module. */
189 static int update(struct wan_device* wandev);
190 static int new_if(struct wan_device* wandev, struct net_device* dev,
191 wanif_conf_t* conf);
193 /* Network device interface */
194 static int if_init(struct net_device* dev);
195 static int if_open(struct net_device* dev);
196 static int if_close(struct net_device* dev);
197 static int if_header(struct sk_buff* skb, struct net_device* dev,
198 unsigned short type, void* daddr, void* saddr,
199 unsigned len);
201 static int if_rebuild_hdr (struct sk_buff *skb);
202 static struct net_device_stats* if_stats(struct net_device* dev);
204 static int if_send(struct sk_buff* skb, struct net_device* dev);
206 /* CHDLC Firmware interface functions */
207 static int chdlc_configure (sdla_t* card, void* data);
208 static int chdlc_comm_enable (sdla_t* card);
209 static int chdlc_read_version (sdla_t* card, char* str);
210 static int chdlc_set_intr_mode (sdla_t* card, unsigned mode);
211 static int chdlc_send (sdla_t* card, void* data, unsigned len);
212 static int chdlc_read_comm_err_stats (sdla_t* card);
213 static int chdlc_read_op_stats (sdla_t* card);
214 static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
217 static int chdlc_disable_comm_shutdown (sdla_t *card);
218 static void if_tx_timeout(struct net_device *dev);
220 /* Miscellaneous CHDLC Functions */
221 static int set_chdlc_config (sdla_t* card);
222 static void init_chdlc_tx_rx_buff( sdla_t* card);
223 static int process_chdlc_exception(sdla_t *card);
224 static int process_global_exception(sdla_t *card);
225 static int update_comms_stats(sdla_t* card,
226 chdlc_private_area_t* chdlc_priv_area);
227 static int configure_ip (sdla_t* card);
228 static int unconfigure_ip (sdla_t* card);
229 static void process_route(sdla_t *card);
230 static void port_set_state (sdla_t *card, int);
231 static int config_chdlc (sdla_t *card);
232 static void disable_comm (sdla_t *card);
234 static void trigger_chdlc_poll(struct net_device *dev);
235 static void chdlc_poll(struct net_device *dev);
236 static void chdlc_poll_delay (unsigned long dev_ptr);
239 /* Miscellaneous asynchronous interface Functions */
240 static int set_asy_config (sdla_t* card);
241 static int asy_comm_enable (sdla_t* card);
243 /* Interrupt handlers */
244 static void wpc_isr (sdla_t* card);
245 static void rx_intr (sdla_t* card);
246 static void timer_intr(sdla_t *);
248 /* Bottom half handlers */
249 static void chdlc_work(struct net_device *dev);
250 static int chdlc_work_cleanup(struct net_device *dev);
251 static int bh_enqueue(struct net_device *dev, struct sk_buff *skb);
253 /* Miscellaneous functions */
254 static int chk_bcast_mcast_addr(sdla_t* card, struct net_device* dev,
255 struct sk_buff *skb);
256 static int reply_udp( unsigned char *data, unsigned int mbox_len );
257 static int intr_test( sdla_t* card);
258 static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
259 static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
260 struct sk_buff *skb, struct net_device* dev,
261 chdlc_private_area_t* chdlc_priv_area);
262 static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
263 chdlc_private_area_t* chdlc_priv_area);
264 static unsigned short calc_checksum (char *, int);
265 static void s508_lock (sdla_t *card, unsigned long *smp_flags);
266 static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
269 static int Intr_test_counter;
271 /* TTY Global Definitions */
273 #define NR_PORTS 4
274 #define WAN_TTY_MAJOR 226
275 #define WAN_TTY_MINOR 0
277 #define WAN_CARD(port) (tty_card_map[port])
278 #define MIN_PORT 0
279 #define MAX_PORT NR_PORTS-1
281 #define CRC_LENGTH 2
283 static int wanpipe_tty_init(sdla_t *card);
284 static void wanpipe_tty_receive(sdla_t *, unsigned, unsigned int);
285 static void wanpipe_tty_trigger_poll(sdla_t *card);
287 static struct tty_driver serial_driver;
288 static int tty_init_cnt=0;
290 static struct serial_state rs_table[NR_PORTS];
292 static char tty_driver_mode=WANOPT_TTY_SYNC;
294 static char *opt_decode[] = {"NONE","CRTSCTS","XONXOFF-RX",
295 "CRTSCTS XONXOFF-RX","XONXOFF-TX",
296 "CRTSCTS XONXOFF-TX","CRTSCTS XONXOFF"};
297 static char *p_decode[] = {"NONE","ODD","EVEN"};
299 static void* tty_card_map[NR_PORTS] = {NULL,NULL,NULL,NULL};
302 /****** Public Functions ****************************************************/
304 /*============================================================================
305 * Cisco HDLC protocol initialization routine.
307 * This routine is called by the main WANPIPE module during setup. At this
308 * point adapter is completely initialized and firmware is running.
309 * o read firmware version (to make sure it's alive)
310 * o configure adapter
311 * o initialize protocol-specific fields of the adapter data space.
313 * Return: 0 o.k.
314 * < 0 failure.
316 int wpc_init (sdla_t* card, wandev_conf_t* conf)
318 unsigned char port_num;
319 int err;
320 unsigned long max_permitted_baud = 0;
321 SHARED_MEMORY_INFO_STRUCT *flags;
323 union
325 char str[80];
326 } u;
327 volatile CHDLC_MAILBOX_STRUCT* mb;
328 CHDLC_MAILBOX_STRUCT* mb1;
329 unsigned long timeout;
331 /* Verify configuration ID */
332 if (conf->config_id != WANCONFIG_CHDLC) {
333 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
334 card->devname, conf->config_id);
335 return -EINVAL;
338 /* Find out which Port to use */
339 if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
340 if (card->next){
342 if (conf->comm_port != card->next->u.c.comm_port){
343 card->u.c.comm_port = conf->comm_port;
344 }else{
345 printk(KERN_INFO "%s: ERROR - %s port used!\n",
346 card->wandev.name, PORT(conf->comm_port));
347 return -EINVAL;
349 }else{
350 card->u.c.comm_port = conf->comm_port;
352 }else{
353 printk(KERN_INFO "%s: ERROR - Invalid Port Selected!\n",
354 card->wandev.name);
355 return -EINVAL;
359 /* Initialize protocol-specific fields */
360 if(card->hw.type != SDLA_S514){
362 if (card->u.c.comm_port == WANOPT_PRI){
363 card->mbox = (void *) card->hw.dpmbase;
364 }else{
365 card->mbox = (void *) card->hw.dpmbase +
366 SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
368 }else{
369 /* for a S514 adapter, set a pointer to the actual mailbox in the */
370 /* allocated virtual memory area */
371 if (card->u.c.comm_port == WANOPT_PRI){
372 card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
373 }else{
374 card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
378 mb = mb1 = card->mbox;
380 if (!card->configured){
382 /* The board will place an 'I' in the return code to indicate that it is
383 ready to accept commands. We expect this to be completed in less
384 than 1 second. */
386 timeout = jiffies;
387 while (mb->return_code != 'I') /* Wait 1s for board to initialize */
388 if ((jiffies - timeout) > 1*HZ) break;
390 if (mb->return_code != 'I') {
391 printk(KERN_INFO
392 "%s: Initialization not completed by adapter\n",
393 card->devname);
394 printk(KERN_INFO "Please contact Sangoma representative.\n");
395 return -EIO;
399 /* Read firmware version. Note that when adapter initializes, it
400 * clears the mailbox, so it may appear that the first command was
401 * executed successfully when in fact it was merely erased. To work
402 * around this, we execute the first command twice.
405 if (chdlc_read_version(card, u.str))
406 return -EIO;
408 printk(KERN_INFO "%s: Running Cisco HDLC firmware v%s\n",
409 card->devname, u.str);
411 card->isr = &wpc_isr;
412 card->poll = NULL;
413 card->exec = NULL;
414 card->wandev.update = &update;
415 card->wandev.new_if = &new_if;
416 card->wandev.del_if = NULL;
417 card->wandev.udp_port = conf->udp_port;
418 card->disable_comm = &disable_comm;
419 card->wandev.new_if_cnt = 0;
421 /* reset the number of times the 'update()' proc has been called */
422 card->u.c.update_call_count = 0;
424 card->wandev.ttl = conf->ttl;
425 card->wandev.interface = conf->interface;
427 if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
428 card->hw.type != SDLA_S514){
429 printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n",
430 card->devname, PORT(card->u.c.comm_port));
431 return -EIO;
434 card->wandev.clocking = conf->clocking;
436 port_num = card->u.c.comm_port;
438 /* in API mode, we can configure for "receive only" buffering */
439 if(card->hw.type == SDLA_S514) {
440 card->u.c.receive_only = conf->receive_only;
441 if(conf->receive_only) {
442 printk(KERN_INFO
443 "%s: Configured for 'receive only' mode\n",
444 card->devname);
448 /* Setup Port Bps */
450 if(card->wandev.clocking) {
451 if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
452 /* For Primary Port 0 */
453 max_permitted_baud =
454 (card->hw.type == SDLA_S514) ?
455 PRI_MAX_BAUD_RATE_S514 :
456 PRI_MAX_BAUD_RATE_S508;
458 }else if(port_num == WANOPT_SEC) {
459 /* For Secondary Port 1 */
460 max_permitted_baud =
461 (card->hw.type == SDLA_S514) ?
462 SEC_MAX_BAUD_RATE_S514 :
463 SEC_MAX_BAUD_RATE_S508;
466 if(conf->bps > max_permitted_baud) {
467 conf->bps = max_permitted_baud;
468 printk(KERN_INFO "%s: Baud too high!\n",
469 card->wandev.name);
470 printk(KERN_INFO "%s: Baud rate set to %lu bps\n",
471 card->wandev.name, max_permitted_baud);
473 card->wandev.bps = conf->bps;
474 }else{
475 card->wandev.bps = 0;
478 /* Setup the Port MTU */
479 if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
481 /* For Primary Port 0 */
482 card->wandev.mtu =
483 (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
484 min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
485 CHDLC_DFLT_DATA_LEN;
486 } else if(port_num == WANOPT_SEC) {
487 /* For Secondary Port 1 */
488 card->wandev.mtu =
489 (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
490 min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
491 CHDLC_DFLT_DATA_LEN;
494 /* Set up the interrupt status area */
495 /* Read the CHDLC Configuration and obtain:
496 * Ptr to shared memory infor struct
497 * Use this pointer to calculate the value of card->u.c.flags !
499 mb1->buffer_length = 0;
500 mb1->command = READ_CHDLC_CONFIGURATION;
501 err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
502 if(err != COMMAND_OK) {
503 if(card->hw.type != SDLA_S514)
504 enable_irq(card->hw.irq);
506 chdlc_error(card, err, mb1);
507 return -EIO;
510 if(card->hw.type == SDLA_S514){
511 card->u.c.flags = (void *)(card->hw.dpmbase +
512 (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
513 ptr_shared_mem_info_struct));
514 }else{
515 card->u.c.flags = (void *)(card->hw.dpmbase +
516 (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
517 ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
520 flags = card->u.c.flags;
522 /* This is for the ports link state */
523 card->wandev.state = WAN_DUALPORT;
524 card->u.c.state = WAN_DISCONNECTED;
527 if (!card->wandev.piggyback){
528 int err;
530 /* Perform interrupt testing */
531 err = intr_test(card);
533 if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
534 printk(KERN_INFO "%s: Interrupt test failed (%i)\n",
535 card->devname, Intr_test_counter);
536 printk(KERN_INFO "%s: Please choose another interrupt\n",
537 card->devname);
538 return -EIO;
541 printk(KERN_INFO "%s: Interrupt test passed (%i)\n",
542 card->devname, Intr_test_counter);
543 card->configured = 1;
546 if ((card->tty_opt=conf->tty) == WANOPT_YES){
547 int err;
548 card->tty_minor = conf->tty_minor;
550 /* On ASYNC connections internal clocking
551 * is mandatory */
552 if ((card->u.c.async_mode = conf->tty_mode)){
553 card->wandev.clocking = 1;
555 err=wanpipe_tty_init(card);
556 if (err){
557 return err;
559 }else{
562 if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
563 printk (KERN_INFO "%s:
564 Failed to set interrupt triggers!\n",
565 card->devname);
566 return -EIO;
569 /* Mask the Timer interrupt */
570 flags->interrupt_info_struct.interrupt_permission &=
571 ~APP_INT_ON_TIMER;
574 /* If we are using CHDLC in backup mode, this flag will
575 * indicate not to look for IP addresses in config_chdlc()*/
576 card->u.c.backup = conf->backup;
578 printk(KERN_INFO "\n");
580 return 0;
583 /******* WAN Device Driver Entry Points *************************************/
585 /*============================================================================
586 * Update device status & statistics
587 * This procedure is called when updating the PROC file system and returns
588 * various communications statistics. These statistics are accumulated from 3
589 * different locations:
590 * 1) The 'if_stats' recorded for the device.
591 * 2) Communication error statistics on the adapter.
592 * 3) CHDLC operational statistics on the adapter.
593 * The board level statistics are read during a timer interrupt. Note that we
594 * read the error and operational statistics during consecitive timer ticks so
595 * as to minimize the time that we are inside the interrupt handler.
598 static int update(struct wan_device* wandev)
600 sdla_t* card = wandev->private;
601 struct net_device* dev;
602 volatile chdlc_private_area_t* chdlc_priv_area;
603 SHARED_MEMORY_INFO_STRUCT *flags;
604 unsigned long timeout;
606 /* sanity checks */
607 if((wandev == NULL) || (wandev->private == NULL))
608 return -EFAULT;
610 if(wandev->state == WAN_UNCONFIGURED)
611 return -ENODEV;
613 /* more sanity checks */
614 if(!card->u.c.flags)
615 return -ENODEV;
617 if(test_bit(PERI_CRIT, (void*)&card->wandev.critical))
618 return -EAGAIN;
620 if((dev=card->wandev.dev) == NULL)
621 return -ENODEV;
623 if((chdlc_priv_area=dev->priv) == NULL)
624 return -ENODEV;
626 flags = card->u.c.flags;
627 if(chdlc_priv_area->update_comms_stats){
628 return -EAGAIN;
631 /* we will need 2 timer interrupts to complete the */
632 /* reading of the statistics */
633 chdlc_priv_area->update_comms_stats = 2;
634 flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
635 chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
637 /* wait a maximum of 1 second for the statistics to be updated */
638 timeout = jiffies;
639 for(;;) {
640 if(chdlc_priv_area->update_comms_stats == 0)
641 break;
642 if ((jiffies - timeout) > (1 * HZ)){
643 chdlc_priv_area->update_comms_stats = 0;
644 chdlc_priv_area->timer_int_enabled &=
645 ~TMR_INT_ENABLED_UPDATE;
646 return -EAGAIN;
650 return 0;
654 /*============================================================================
655 * Create new logical channel.
656 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
657 * handled.
658 * o parse media- and hardware-specific configuration
659 * o make sure that a new channel can be created
660 * o allocate resources, if necessary
661 * o prepare network device structure for registaration.
663 * Return: 0 o.k.
664 * < 0 failure (channel will not be created)
666 static int new_if(struct wan_device* wandev, struct net_device* dev,
667 wanif_conf_t* conf)
669 sdla_t* card = wandev->private;
670 chdlc_private_area_t* chdlc_priv_area;
673 printk(KERN_INFO "%s: Configuring Interface: %s\n",
674 card->devname, conf->name);
676 if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
677 printk(KERN_INFO "%s: Invalid interface name!\n",
678 card->devname);
679 return -EINVAL;
682 /* allocate and initialize private data */
683 chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
685 if(chdlc_priv_area == NULL)
686 return -ENOMEM;
688 memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
690 chdlc_priv_area->card = card;
691 chdlc_priv_area->common.sk = NULL;
692 chdlc_priv_area->common.func = NULL;
694 /* initialize data */
695 strcpy(card->u.c.if_name, conf->name);
697 if(card->wandev.new_if_cnt > 0) {
698 kfree(chdlc_priv_area);
699 return -EEXIST;
702 card->wandev.new_if_cnt++;
704 chdlc_priv_area->TracingEnabled = 0;
705 chdlc_priv_area->route_status = NO_ROUTE;
706 chdlc_priv_area->route_removed = 0;
708 card->u.c.async_mode = conf->async_mode;
710 /* setup for asynchronous mode */
711 if(conf->async_mode) {
712 printk(KERN_INFO "%s: Configuring for asynchronous mode\n",
713 wandev->name);
715 if(card->u.c.comm_port == WANOPT_PRI) {
716 printk(KERN_INFO
717 "%s:Asynchronous mode on secondary port only\n",
718 wandev->name);
719 kfree(chdlc_priv_area);
720 return -EINVAL;
723 if(strcmp(conf->usedby, "WANPIPE") == 0) {
724 printk(KERN_INFO
725 "%s: Running in WANIPE Async Mode\n", wandev->name);
726 card->u.c.usedby = WANPIPE;
727 }else{
728 card->u.c.usedby = API;
731 if(!card->wandev.clocking) {
732 printk(KERN_INFO
733 "%s: Asynch. clocking must be 'Internal'\n",
734 wandev->name);
735 kfree(chdlc_priv_area);
736 return -EINVAL;
739 if((card->wandev.bps < MIN_ASY_BAUD_RATE) ||
740 (card->wandev.bps > MAX_ASY_BAUD_RATE)) {
741 printk(KERN_INFO "%s: Selected baud rate is invalid.\n",
742 wandev->name);
743 printk(KERN_INFO "Must be between %u and %u bps.\n",
744 MIN_ASY_BAUD_RATE, MAX_ASY_BAUD_RATE);
745 kfree(chdlc_priv_area);
746 return -EINVAL;
749 card->u.c.api_options = 0;
750 if (conf->asy_data_trans == WANOPT_YES) {
751 card->u.c.api_options |= ASY_RX_DATA_TRANSPARENT;
754 card->u.c.protocol_options = 0;
755 if (conf->rts_hs_for_receive == WANOPT_YES) {
756 card->u.c.protocol_options |= ASY_RTS_HS_FOR_RX;
758 if (conf->xon_xoff_hs_for_receive == WANOPT_YES) {
759 card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_RX;
761 if (conf->xon_xoff_hs_for_transmit == WANOPT_YES) {
762 card->u.c.protocol_options |= ASY_XON_XOFF_HS_FOR_TX;
764 if (conf->dcd_hs_for_transmit == WANOPT_YES) {
765 card->u.c.protocol_options |= ASY_DCD_HS_FOR_TX;
767 if (conf->cts_hs_for_transmit == WANOPT_YES) {
768 card->u.c.protocol_options |= ASY_CTS_HS_FOR_TX;
771 card->u.c.tx_bits_per_char = conf->tx_bits_per_char;
772 card->u.c.rx_bits_per_char = conf->rx_bits_per_char;
773 card->u.c.stop_bits = conf->stop_bits;
774 card->u.c.parity = conf->parity;
775 card->u.c.break_timer = conf->break_timer;
776 card->u.c.inter_char_timer = conf->inter_char_timer;
777 card->u.c.rx_complete_length = conf->rx_complete_length;
778 card->u.c.xon_char = conf->xon_char;
780 } else { /* setup for synchronous mode */
782 card->u.c.protocol_options = 0;
783 if (conf->ignore_dcd == WANOPT_YES){
784 card->u.c.protocol_options |= IGNORE_DCD_FOR_LINK_STAT;
786 if (conf->ignore_cts == WANOPT_YES){
787 card->u.c.protocol_options |= IGNORE_CTS_FOR_LINK_STAT;
790 if (conf->ignore_keepalive == WANOPT_YES) {
791 card->u.c.protocol_options |=
792 IGNORE_KPALV_FOR_LINK_STAT;
793 card->u.c.kpalv_tx = MIN_Tx_KPALV_TIMER;
794 card->u.c.kpalv_rx = MIN_Rx_KPALV_TIMER;
795 card->u.c.kpalv_err = MIN_KPALV_ERR_TOL;
797 } else { /* Do not ignore keepalives */
798 card->u.c.kpalv_tx =
799 ((conf->keepalive_tx_tmr - MIN_Tx_KPALV_TIMER)
800 >= 0) ?
801 min_t(unsigned int, conf->keepalive_tx_tmr,MAX_Tx_KPALV_TIMER) :
802 DEFAULT_Tx_KPALV_TIMER;
804 card->u.c.kpalv_rx =
805 ((conf->keepalive_rx_tmr - MIN_Rx_KPALV_TIMER)
806 >= 0) ?
807 min_t(unsigned int, conf->keepalive_rx_tmr,MAX_Rx_KPALV_TIMER) :
808 DEFAULT_Rx_KPALV_TIMER;
810 card->u.c.kpalv_err =
811 ((conf->keepalive_err_margin-MIN_KPALV_ERR_TOL)
812 >= 0) ?
813 min_t(unsigned int, conf->keepalive_err_margin,
814 MAX_KPALV_ERR_TOL) :
815 DEFAULT_KPALV_ERR_TOL;
818 /* Setup slarp timer to control delay between slarps */
819 card->u.c.slarp_timer =
820 ((conf->slarp_timer - MIN_SLARP_REQ_TIMER) >= 0) ?
821 min_t(unsigned int, conf->slarp_timer, MAX_SLARP_REQ_TIMER) :
822 DEFAULT_SLARP_REQ_TIMER;
824 if (conf->hdlc_streaming == WANOPT_YES) {
825 printk(KERN_INFO "%s: Enabling HDLC STREAMING Mode\n",
826 wandev->name);
827 card->u.c.protocol_options = HDLC_STREAMING_MODE;
830 if ((chdlc_priv_area->true_if_encoding = conf->true_if_encoding) == WANOPT_YES){
831 printk(KERN_INFO
832 "%s: Enabling, true interface type encoding.\n",
833 card->devname);
836 /* Setup wanpipe as a router (WANPIPE) or as an API */
837 if( strcmp(conf->usedby, "WANPIPE") == 0) {
839 printk(KERN_INFO "%s: Running in WANPIPE mode!\n",
840 wandev->name);
841 card->u.c.usedby = WANPIPE;
843 /* Option to bring down the interface when
844 * the link goes down */
845 if (conf->if_down){
846 set_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down);
847 printk(KERN_INFO
848 "%s: Dynamic interface configuration enabled\n",
849 card->devname);
852 } else if( strcmp(conf->usedby, "API") == 0) {
853 card->u.c.usedby = API;
854 printk(KERN_INFO "%s: Running in API mode !\n",
855 wandev->name);
859 /* Tells us that if this interface is a
860 * gateway or not */
861 if ((chdlc_priv_area->gateway = conf->gateway) == WANOPT_YES){
862 printk(KERN_INFO "%s: Interface %s is set as a gateway.\n",
863 card->devname,card->u.c.if_name);
866 /* Get Multicast Information */
867 chdlc_priv_area->mc = conf->mc;
869 /* prepare network device data space for registration */
870 strcpy(dev->name,card->u.c.if_name);
872 dev->init = &if_init;
873 dev->priv = chdlc_priv_area;
875 /* Initialize the polling work routine */
876 INIT_WORK(&chdlc_priv_area->poll_work, (void*)(void*)chdlc_poll, dev);
878 /* Initialize the polling delay timer */
879 init_timer(&chdlc_priv_area->poll_delay_timer);
880 chdlc_priv_area->poll_delay_timer.data = (unsigned long)dev;
881 chdlc_priv_area->poll_delay_timer.function = chdlc_poll_delay;
883 printk(KERN_INFO "\n");
885 return 0;
889 /****** Network Device Interface ********************************************/
891 /*============================================================================
892 * Initialize Linux network interface.
894 * This routine is called only once for each interface, during Linux network
895 * interface registration. Returning anything but zero will fail interface
896 * registration.
898 static int if_init(struct net_device* dev)
900 chdlc_private_area_t* chdlc_priv_area = dev->priv;
901 sdla_t* card = chdlc_priv_area->card;
902 struct wan_device* wandev = &card->wandev;
904 /* Initialize device driver entry points */
905 dev->open = &if_open;
906 dev->stop = &if_close;
907 dev->hard_header = &if_header;
908 dev->rebuild_header = &if_rebuild_hdr;
909 dev->hard_start_xmit = &if_send;
910 dev->get_stats = &if_stats;
911 dev->tx_timeout = &if_tx_timeout;
912 dev->watchdog_timeo = TX_TIMEOUT;
914 /* Initialize media-specific parameters */
915 dev->flags |= IFF_POINTOPOINT;
916 dev->flags |= IFF_NOARP;
918 /* Enable Mulitcasting if user selected */
919 if (chdlc_priv_area->mc == WANOPT_YES){
920 dev->flags |= IFF_MULTICAST;
923 if (chdlc_priv_area->true_if_encoding){
924 dev->type = ARPHRD_HDLC; /* This breaks the tcpdump */
925 }else{
926 dev->type = ARPHRD_PPP;
929 dev->mtu = card->wandev.mtu;
930 /* for API usage, add the API header size to the requested MTU size */
931 if(card->u.c.usedby == API) {
932 dev->mtu += sizeof(api_tx_hdr_t);
935 dev->hard_header_len = CHDLC_HDR_LEN;
937 /* Initialize hardware parameters */
938 dev->irq = wandev->irq;
939 dev->dma = wandev->dma;
940 dev->base_addr = wandev->ioport;
941 dev->mem_start = wandev->maddr;
942 dev->mem_end = wandev->maddr + wandev->msize - 1;
944 /* Set transmit buffer queue length
945 * If too low packets will not be retransmitted
946 * by stack.
948 dev->tx_queue_len = 100;
949 SET_MODULE_OWNER(dev);
951 return 0;
954 /*============================================================================
955 * Open network interface.
956 * o enable communications and interrupts.
957 * o prevent module from unloading by incrementing use count
959 * Return 0 if O.k. or errno.
961 static int if_open(struct net_device* dev)
963 chdlc_private_area_t* chdlc_priv_area = dev->priv;
964 sdla_t* card = chdlc_priv_area->card;
965 struct timeval tv;
966 int err = 0;
968 /* Only one open per interface is allowed */
970 if (netif_running(dev))
971 return -EBUSY;
973 /* Initialize the work queue entry */
974 chdlc_priv_area->tq_working=0;
976 INIT_WORK(&chdlc_priv_area->common.wanpipe_work,
977 (void *)(void *)chdlc_work, dev);
979 /* Allocate and initialize BH circular buffer */
980 /* Add 1 to MAX_BH_BUFF so we don't have test with (MAX_BH_BUFF-1) */
981 chdlc_priv_area->bh_head = kmalloc((sizeof(bh_data_t)*(MAX_BH_BUFF+1)),GFP_ATOMIC);
982 memset(chdlc_priv_area->bh_head,0,(sizeof(bh_data_t)*(MAX_BH_BUFF+1)));
983 atomic_set(&chdlc_priv_area->bh_buff_used, 0);
985 do_gettimeofday(&tv);
986 chdlc_priv_area->router_start_time = tv.tv_sec;
988 netif_start_queue(dev);
990 wanpipe_open(card);
992 /* TTY is configured during wanpipe_set_termios
993 * call, not here */
994 if (card->tty_opt)
995 return err;
997 set_bit(0,&chdlc_priv_area->config_chdlc);
998 chdlc_priv_area->config_chdlc_timeout=jiffies;
1000 /* Start the CHDLC configuration after 1sec delay.
1001 * This will give the interface initilization time
1002 * to finish its configuration */
1003 mod_timer(&chdlc_priv_area->poll_delay_timer, jiffies + HZ);
1004 return err;
1007 /*============================================================================
1008 * Close network interface.
1009 * o if this is the last close, then disable communications and interrupts.
1010 * o reset flags.
1012 static int if_close(struct net_device* dev)
1014 chdlc_private_area_t* chdlc_priv_area = dev->priv;
1015 sdla_t* card = chdlc_priv_area->card;
1017 if (chdlc_priv_area->bh_head){
1018 int i;
1019 struct sk_buff *skb;
1021 for (i=0; i<(MAX_BH_BUFF+1); i++){
1022 skb = ((bh_data_t *)&chdlc_priv_area->bh_head[i])->skb;
1023 if (skb != NULL){
1024 dev_kfree_skb_any(skb);
1027 kfree(chdlc_priv_area->bh_head);
1028 chdlc_priv_area->bh_head=NULL;
1031 netif_stop_queue(dev);
1032 wanpipe_close(card);
1033 del_timer(&chdlc_priv_area->poll_delay_timer);
1034 return 0;
1037 static void disable_comm (sdla_t *card)
1039 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1041 if (card->u.c.comm_enabled){
1042 chdlc_disable_comm_shutdown (card);
1043 }else{
1044 flags->interrupt_info_struct.interrupt_permission = 0;
1047 if (!tty_init_cnt)
1048 return;
1050 if (card->tty_opt){
1051 struct serial_state * state;
1052 if (!(--tty_init_cnt)){
1053 int e1;
1054 serial_driver.refcount=0;
1056 if ((e1 = tty_unregister_driver(&serial_driver)))
1057 printk("SERIAL: failed to unregister serial driver (%d)\n",
1058 e1);
1059 printk(KERN_INFO "%s: Unregistering TTY Driver, Major %i\n",
1060 card->devname,WAN_TTY_MAJOR);
1062 card->tty=NULL;
1063 tty_card_map[card->tty_minor]=NULL;
1064 state = &rs_table[card->tty_minor];
1065 memset(state, 0, sizeof(*state));
1067 return;
1071 /*============================================================================
1072 * Build media header.
1074 * The trick here is to put packet type (Ethertype) into 'protocol' field of
1075 * the socket buffer, so that we don't forget it. If packet type is not
1076 * supported, set skb->protocol to 0 and discard packet later.
1078 * Return: media header length.
1080 static int if_header(struct sk_buff* skb, struct net_device* dev,
1081 unsigned short type, void* daddr, void* saddr,
1082 unsigned len)
1084 skb->protocol = htons(type);
1086 return CHDLC_HDR_LEN;
1090 /*============================================================================
1091 * Handle transmit timeout event from netif watchdog
1093 static void if_tx_timeout(struct net_device *dev)
1095 chdlc_private_area_t* chan = dev->priv;
1096 sdla_t *card = chan->card;
1098 /* If our device stays busy for at least 5 seconds then we will
1099 * kick start the device by making dev->tbusy = 0. We expect
1100 * that our device never stays busy more than 5 seconds. So this
1101 * is only used as a last resort.
1104 ++card->wandev.stats.collisions;
1106 printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
1107 netif_wake_queue (dev);
1112 /*============================================================================
1113 * Re-build media header.
1115 * Return: 1 physical address resolved.
1116 * 0 physical address not resolved
1118 static int if_rebuild_hdr (struct sk_buff *skb)
1120 return 1;
1124 /*============================================================================
1125 * Send a packet on a network interface.
1126 * o set tbusy flag (marks start of the transmission) to block a timer-based
1127 * transmit from overlapping.
1128 * o check link state. If link is not up, then drop the packet.
1129 * o execute adapter send command.
1130 * o free socket buffer
1132 * Return: 0 complete (socket buffer must be freed)
1133 * non-0 packet may be re-transmitted (tbusy must be set)
1135 * Notes:
1136 * 1. This routine is called either by the protocol stack or by the "net
1137 * bottom half" (with interrupts enabled).
1138 * 2. Setting tbusy flag will inhibit further transmit requests from the
1139 * protocol stack and can be used for flow control with protocol layer.
1141 static int if_send(struct sk_buff* skb, struct net_device* dev)
1143 chdlc_private_area_t *chdlc_priv_area = dev->priv;
1144 sdla_t *card = chdlc_priv_area->card;
1145 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1146 INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
1147 int udp_type = 0;
1148 unsigned long smp_flags;
1149 int err=0;
1151 netif_stop_queue(dev);
1153 if (skb == NULL){
1154 /* If we get here, some higher layer thinks we've missed an
1155 * tx-done interrupt.
1157 printk(KERN_INFO "%s: interface %s got kicked!\n",
1158 card->devname, dev->name);
1160 netif_wake_queue(dev);
1161 return 0;
1164 if (ntohs(skb->protocol) != htons(PVC_PROT)){
1166 /* check the udp packet type */
1168 udp_type = udp_pkt_type(skb, card);
1170 if (udp_type == UDP_CPIPE_TYPE){
1171 if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
1172 chdlc_priv_area)){
1173 chdlc_int->interrupt_permission |=
1174 APP_INT_ON_TIMER;
1176 netif_start_queue(dev);
1177 return 0;
1180 /* check to see if the source IP address is a broadcast or */
1181 /* multicast IP address */
1182 if(chk_bcast_mcast_addr(card, dev, skb)){
1183 ++card->wandev.stats.tx_dropped;
1184 dev_kfree_skb_any(skb);
1185 netif_start_queue(dev);
1186 return 0;
1190 /* Lock the 508 Card: SMP is supported */
1191 if(card->hw.type != SDLA_S514){
1192 s508_lock(card,&smp_flags);
1195 if(test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
1197 printk(KERN_INFO "%s: Critical in if_send: %lx\n",
1198 card->wandev.name,card->wandev.critical);
1199 ++card->wandev.stats.tx_dropped;
1200 netif_start_queue(dev);
1201 goto if_send_exit_crit;
1204 if(card->u.c.state != WAN_CONNECTED){
1205 ++card->wandev.stats.tx_dropped;
1206 netif_start_queue(dev);
1208 }else if(!skb->protocol){
1209 ++card->wandev.stats.tx_errors;
1210 netif_start_queue(dev);
1212 }else {
1213 void* data = skb->data;
1214 unsigned len = skb->len;
1215 unsigned char attr;
1217 /* If it's an API packet pull off the API
1218 * header. Also check that the packet size
1219 * is larger than the API header
1221 if (card->u.c.usedby == API){
1222 api_tx_hdr_t* api_tx_hdr;
1224 /* discard the frame if we are configured for */
1225 /* 'receive only' mode or if there is no data */
1226 if (card->u.c.receive_only ||
1227 (len <= sizeof(api_tx_hdr_t))) {
1229 ++card->wandev.stats.tx_dropped;
1230 netif_start_queue(dev);
1231 goto if_send_exit_crit;
1234 api_tx_hdr = (api_tx_hdr_t *)data;
1235 attr = api_tx_hdr->attr;
1236 data += sizeof(api_tx_hdr_t);
1237 len -= sizeof(api_tx_hdr_t);
1240 if(chdlc_send(card, data, len)) {
1241 netif_stop_queue(dev);
1242 }else{
1243 ++card->wandev.stats.tx_packets;
1244 card->wandev.stats.tx_bytes += len;
1246 netif_start_queue(dev);
1248 dev->trans_start = jiffies;
1252 if_send_exit_crit:
1254 if (!(err=netif_queue_stopped(dev))) {
1255 dev_kfree_skb_any(skb);
1256 }else{
1257 chdlc_priv_area->tick_counter = jiffies;
1258 chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
1261 clear_bit(SEND_CRIT, (void*)&card->wandev.critical);
1262 if(card->hw.type != SDLA_S514){
1263 s508_unlock(card,&smp_flags);
1266 return err;
1270 /*============================================================================
1271 * Check to see if the packet to be transmitted contains a broadcast or
1272 * multicast source IP address.
1275 static int chk_bcast_mcast_addr(sdla_t *card, struct net_device* dev,
1276 struct sk_buff *skb)
1278 u32 src_ip_addr;
1279 u32 broadcast_ip_addr = 0;
1280 struct in_device *in_dev;
1282 /* read the IP source address from the outgoing packet */
1283 src_ip_addr = *(u32 *)(skb->data + 12);
1285 /* read the IP broadcast address for the device */
1286 in_dev = dev->ip_ptr;
1287 if(in_dev != NULL) {
1288 struct in_ifaddr *ifa= in_dev->ifa_list;
1289 if(ifa != NULL)
1290 broadcast_ip_addr = ifa->ifa_broadcast;
1291 else
1292 return 0;
1295 /* check if the IP Source Address is a Broadcast address */
1296 if((dev->flags & IFF_BROADCAST) && (src_ip_addr == broadcast_ip_addr)) {
1297 printk(KERN_INFO "%s: Broadcast Source Address silently discarded\n",
1298 card->devname);
1299 return 1;
1302 /* check if the IP Source Address is a Multicast address */
1303 if((ntohl(src_ip_addr) >= 0xE0000001) &&
1304 (ntohl(src_ip_addr) <= 0xFFFFFFFE)) {
1305 printk(KERN_INFO "%s: Multicast Source Address silently discarded\n",
1306 card->devname);
1307 return 1;
1310 return 0;
1314 /*============================================================================
1315 * Reply to UDP Management system.
1316 * Return length of reply.
1318 static int reply_udp( unsigned char *data, unsigned int mbox_len )
1321 unsigned short len, udp_length, temp, ip_length;
1322 unsigned long ip_temp;
1323 int even_bound = 0;
1324 chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data;
1326 /* Set length of packet */
1327 len = sizeof(ip_pkt_t)+
1328 sizeof(udp_pkt_t)+
1329 sizeof(wp_mgmt_t)+
1330 sizeof(cblock_t)+
1331 sizeof(trace_info_t)+
1332 mbox_len;
1334 /* fill in UDP reply */
1335 c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
1337 /* fill in UDP length */
1338 udp_length = sizeof(udp_pkt_t)+
1339 sizeof(wp_mgmt_t)+
1340 sizeof(cblock_t)+
1341 sizeof(trace_info_t)+
1342 mbox_len;
1344 /* put it on an even boundary */
1345 if ( udp_length & 0x0001 ) {
1346 udp_length += 1;
1347 len += 1;
1348 even_bound = 1;
1351 temp = (udp_length<<8)|(udp_length>>8);
1352 c_udp_pkt->udp_pkt.udp_length = temp;
1354 /* swap UDP ports */
1355 temp = c_udp_pkt->udp_pkt.udp_src_port;
1356 c_udp_pkt->udp_pkt.udp_src_port =
1357 c_udp_pkt->udp_pkt.udp_dst_port;
1358 c_udp_pkt->udp_pkt.udp_dst_port = temp;
1360 /* add UDP pseudo header */
1361 temp = 0x1100;
1362 *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp;
1363 temp = (udp_length<<8)|(udp_length>>8);
1364 *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp;
1367 /* calculate UDP checksum */
1368 c_udp_pkt->udp_pkt.udp_checksum = 0;
1369 c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
1371 /* fill in IP length */
1372 ip_length = len;
1373 temp = (ip_length<<8)|(ip_length>>8);
1374 c_udp_pkt->ip_pkt.total_length = temp;
1376 /* swap IP addresses */
1377 ip_temp = c_udp_pkt->ip_pkt.ip_src_address;
1378 c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address;
1379 c_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
1381 /* fill in IP checksum */
1382 c_udp_pkt->ip_pkt.hdr_checksum = 0;
1383 c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));
1385 return len;
1387 } /* reply_udp */
1389 unsigned short calc_checksum (char *data, int len)
1391 unsigned short temp;
1392 unsigned long sum=0;
1393 int i;
1395 for( i = 0; i <len; i+=2 ) {
1396 memcpy(&temp,&data[i],2);
1397 sum += (unsigned long)temp;
1400 while (sum >> 16 ) {
1401 sum = (sum & 0xffffUL) + (sum >> 16);
1404 temp = (unsigned short)sum;
1405 temp = ~temp;
1407 if( temp == 0 )
1408 temp = 0xffff;
1410 return temp;
1414 /*============================================================================
1415 * Get ethernet-style interface statistics.
1416 * Return a pointer to struct enet_statistics.
1418 static struct net_device_stats* if_stats(struct net_device* dev)
1420 sdla_t *my_card;
1421 chdlc_private_area_t* chdlc_priv_area;
1423 if ((chdlc_priv_area=dev->priv) == NULL)
1424 return NULL;
1426 my_card = chdlc_priv_area->card;
1427 return &my_card->wandev.stats;
1431 /****** Cisco HDLC Firmware Interface Functions *******************************/
1433 /*============================================================================
1434 * Read firmware code version.
1435 * Put code version as ASCII string in str.
1437 static int chdlc_read_version (sdla_t* card, char* str)
1439 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1440 int len;
1441 char err;
1442 mb->buffer_length = 0;
1443 mb->command = READ_CHDLC_CODE_VERSION;
1444 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1446 if(err != COMMAND_OK) {
1447 chdlc_error(card,err,mb);
1449 else if (str) { /* is not null */
1450 len = mb->buffer_length;
1451 memcpy(str, mb->data, len);
1452 str[len] = '\0';
1454 return (err);
1457 /*-----------------------------------------------------------------------------
1458 * Configure CHDLC firmware.
1460 static int chdlc_configure (sdla_t* card, void* data)
1462 int err;
1463 CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
1464 int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);
1466 mailbox->buffer_length = data_length;
1467 memcpy(mailbox->data, data, data_length);
1468 mailbox->command = SET_CHDLC_CONFIGURATION;
1469 err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
1471 if (err != COMMAND_OK) chdlc_error (card, err, mailbox);
1473 return err;
1477 /*============================================================================
1478 * Set interrupt mode -- HDLC Version.
1481 static int chdlc_set_intr_mode (sdla_t* card, unsigned mode)
1483 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1484 CHDLC_INT_TRIGGERS_STRUCT* int_data =
1485 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1486 int err;
1488 int_data->CHDLC_interrupt_triggers = mode;
1489 int_data->IRQ = card->hw.irq;
1490 int_data->interrupt_timer = 1;
1492 mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
1493 mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
1494 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1495 if (err != COMMAND_OK)
1496 chdlc_error (card, err, mb);
1497 return err;
1501 /*===========================================================
1502 * chdlc_disable_comm_shutdown
1504 * Shutdown() disables the communications. We must
1505 * have a sparate functions, because we must not
1506 * call chdlc_error() hander since the private
1507 * area has already been replaced */
1509 static int chdlc_disable_comm_shutdown (sdla_t *card)
1511 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1512 CHDLC_INT_TRIGGERS_STRUCT* int_data =
1513 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1514 int err;
1516 /* Disable Interrutps */
1517 int_data->CHDLC_interrupt_triggers = 0;
1518 int_data->IRQ = card->hw.irq;
1519 int_data->interrupt_timer = 1;
1521 mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
1522 mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
1523 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1525 /* Disable Communications */
1527 if (card->u.c.async_mode) {
1528 mb->command = DISABLE_ASY_COMMUNICATIONS;
1529 }else{
1530 mb->command = DISABLE_CHDLC_COMMUNICATIONS;
1533 mb->buffer_length = 0;
1534 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1536 card->u.c.comm_enabled = 0;
1538 return 0;
1541 /*============================================================================
1542 * Enable communications.
1545 static int chdlc_comm_enable (sdla_t* card)
1547 int err;
1548 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1550 mb->buffer_length = 0;
1551 mb->command = ENABLE_CHDLC_COMMUNICATIONS;
1552 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1553 if (err != COMMAND_OK)
1554 chdlc_error(card, err, mb);
1555 else
1556 card->u.c.comm_enabled = 1;
1558 return err;
1561 /*============================================================================
1562 * Read communication error statistics.
1564 static int chdlc_read_comm_err_stats (sdla_t* card)
1566 int err;
1567 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1569 mb->buffer_length = 0;
1570 mb->command = READ_COMMS_ERROR_STATS;
1571 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1572 if (err != COMMAND_OK)
1573 chdlc_error(card,err,mb);
1574 return err;
1578 /*============================================================================
1579 * Read CHDLC operational statistics.
1581 static int chdlc_read_op_stats (sdla_t* card)
1583 int err;
1584 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1586 mb->buffer_length = 0;
1587 mb->command = READ_CHDLC_OPERATIONAL_STATS;
1588 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1589 if (err != COMMAND_OK)
1590 chdlc_error(card,err,mb);
1591 return err;
1595 /*============================================================================
1596 * Update communications error and general packet statistics.
1598 static int update_comms_stats(sdla_t* card,
1599 chdlc_private_area_t* chdlc_priv_area)
1601 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1602 COMMS_ERROR_STATS_STRUCT* err_stats;
1603 CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;
1605 /* on the first timer interrupt, read the comms error statistics */
1606 if(chdlc_priv_area->update_comms_stats == 2) {
1607 if(chdlc_read_comm_err_stats(card))
1608 return 1;
1609 err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data;
1610 card->wandev.stats.rx_over_errors =
1611 err_stats->Rx_overrun_err_count;
1612 card->wandev.stats.rx_crc_errors =
1613 err_stats->CRC_err_count;
1614 card->wandev.stats.rx_frame_errors =
1615 err_stats->Rx_abort_count;
1616 card->wandev.stats.rx_fifo_errors =
1617 err_stats->Rx_dis_pri_bfrs_full_count;
1618 card->wandev.stats.rx_missed_errors =
1619 card->wandev.stats.rx_fifo_errors;
1620 card->wandev.stats.tx_aborted_errors =
1621 err_stats->sec_Tx_abort_count;
1624 /* on the second timer interrupt, read the operational statistics */
1625 else {
1626 if(chdlc_read_op_stats(card))
1627 return 1;
1628 op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data;
1629 card->wandev.stats.rx_length_errors =
1630 (op_stats->Rx_Data_discard_short_count +
1631 op_stats->Rx_Data_discard_long_count);
1634 return 0;
1637 /*============================================================================
1638 * Send packet.
1639 * Return: 0 - o.k.
1640 * 1 - no transmit buffers available
1642 static int chdlc_send (sdla_t* card, void* data, unsigned len)
1644 CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;
1646 if (txbuf->opp_flag)
1647 return 1;
1649 sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);
1651 txbuf->frame_length = len;
1652 txbuf->opp_flag = 1; /* start transmission */
1654 /* Update transmit buffer control fields */
1655 card->u.c.txbuf = ++txbuf;
1657 if ((void*)txbuf > card->u.c.txbuf_last)
1658 card->u.c.txbuf = card->u.c.txbuf_base;
1660 return 0;
1663 /****** Firmware Error Handler **********************************************/
1665 /*============================================================================
1666 * Firmware error handler.
1667 * This routine is called whenever firmware command returns non-zero
1668 * return code.
1670 * Return zero if previous command has to be cancelled.
1672 static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
1674 unsigned cmd = mb->command;
1676 switch (err) {
1678 case CMD_TIMEOUT:
1679 printk(KERN_INFO "%s: command 0x%02X timed out!\n",
1680 card->devname, cmd);
1681 break;
1683 case S514_BOTH_PORTS_SAME_CLK_MODE:
1684 if(cmd == SET_CHDLC_CONFIGURATION) {
1685 printk(KERN_INFO
1686 "%s: Configure both ports for the same clock source\n",
1687 card->devname);
1688 break;
1691 default:
1692 printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
1693 card->devname, cmd, err);
1696 return 0;
1700 /********** Bottom Half Handlers ********************************************/
1702 /* NOTE: There is no API, BH support for Kernels lower than 2.2.X.
1703 * DO NOT INSERT ANY CODE HERE, NOTICE THE
1704 * PREPROCESSOR STATEMENT ABOVE, UNLESS YOU KNOW WHAT YOU ARE
1705 * DOING */
1707 static void chdlc_work(struct net_device * dev)
1709 chdlc_private_area_t* chan = dev->priv;
1710 sdla_t *card = chan->card;
1711 struct sk_buff *skb;
1713 if (atomic_read(&chan->bh_buff_used) == 0){
1714 clear_bit(0, &chan->tq_working);
1715 return;
1718 while (atomic_read(&chan->bh_buff_used)){
1720 skb = ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb;
1722 if (skb != NULL){
1724 if (chan->common.sk == NULL || chan->common.func == NULL){
1725 ++card->wandev.stats.rx_dropped;
1726 dev_kfree_skb_any(skb);
1727 chdlc_work_cleanup(dev);
1728 continue;
1731 if (chan->common.func(skb,dev,chan->common.sk) != 0){
1732 /* Sock full cannot send, queue us for another
1733 * try */
1734 atomic_set(&chan->common.receive_block,1);
1735 return;
1736 }else{
1737 chdlc_work_cleanup(dev);
1739 }else{
1740 chdlc_work_cleanup(dev);
1743 clear_bit(0, &chan->tq_working);
1745 return;
1748 static int chdlc_work_cleanup(struct net_device *dev)
1750 chdlc_private_area_t* chan = dev->priv;
1752 ((bh_data_t *)&chan->bh_head[chan->bh_read])->skb = NULL;
1754 if (chan->bh_read == MAX_BH_BUFF){
1755 chan->bh_read=0;
1756 }else{
1757 ++chan->bh_read;
1760 atomic_dec(&chan->bh_buff_used);
1761 return 0;
1766 static int bh_enqueue(struct net_device *dev, struct sk_buff *skb)
1768 /* Check for full */
1769 chdlc_private_area_t* chan = dev->priv;
1770 sdla_t *card = chan->card;
1772 if (atomic_read(&chan->bh_buff_used) == (MAX_BH_BUFF+1)){
1773 ++card->wandev.stats.rx_dropped;
1774 dev_kfree_skb_any(skb);
1775 return 1;
1778 ((bh_data_t *)&chan->bh_head[chan->bh_write])->skb = skb;
1780 if (chan->bh_write == MAX_BH_BUFF){
1781 chan->bh_write=0;
1782 }else{
1783 ++chan->bh_write;
1786 atomic_inc(&chan->bh_buff_used);
1788 return 0;
1791 /* END OF API BH Support */
1794 /****** Interrupt Handlers **************************************************/
1796 /*============================================================================
1797 * Cisco HDLC interrupt service routine.
1799 static void wpc_isr (sdla_t* card)
1801 struct net_device* dev;
1802 SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1803 int i;
1804 sdla_t *my_card;
1807 /* Check for which port the interrupt has been generated
1808 * Since Secondary Port is piggybacking on the Primary
1809 * the check must be done here.
1812 flags = card->u.c.flags;
1813 if (!flags->interrupt_info_struct.interrupt_type){
1814 /* Check for a second port (piggybacking) */
1815 if ((my_card = card->next)){
1816 flags = my_card->u.c.flags;
1817 if (flags->interrupt_info_struct.interrupt_type){
1818 card = my_card;
1819 card->isr(card);
1820 return;
1825 flags = card->u.c.flags;
1826 card->in_isr = 1;
1827 dev = card->wandev.dev;
1829 /* If we get an interrupt with no network device, stop the interrupts
1830 * and issue an error */
1831 if (!card->tty_opt && !dev &&
1832 flags->interrupt_info_struct.interrupt_type !=
1833 COMMAND_COMPLETE_APP_INT_PEND){
1835 goto isr_done;
1838 /* if critical due to peripheral operations
1839 * ie. update() or getstats() then reset the interrupt and
1840 * wait for the board to retrigger.
1842 if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
1843 printk(KERN_INFO "ISR CRIT TO PERI\n");
1844 goto isr_done;
1847 /* On a 508 Card, if critical due to if_send
1848 * Major Error !!! */
1849 if(card->hw.type != SDLA_S514) {
1850 if(test_bit(SEND_CRIT, (void*)&card->wandev.critical)) {
1851 printk(KERN_INFO "%s: Critical while in ISR: %lx\n",
1852 card->devname, card->wandev.critical);
1853 card->in_isr = 0;
1854 flags->interrupt_info_struct.interrupt_type = 0;
1855 return;
1859 switch(flags->interrupt_info_struct.interrupt_type) {
1861 case RX_APP_INT_PEND: /* 0x01: receive interrupt */
1862 rx_intr(card);
1863 break;
1865 case TX_APP_INT_PEND: /* 0x02: transmit interrupt */
1866 flags->interrupt_info_struct.interrupt_permission &=
1867 ~APP_INT_ON_TX_FRAME;
1869 if (card->tty_opt){
1870 wanpipe_tty_trigger_poll(card);
1871 break;
1874 if (dev && netif_queue_stopped(dev)){
1875 if (card->u.c.usedby == API){
1876 netif_start_queue(dev);
1877 wakeup_sk_bh(dev);
1878 }else{
1879 netif_wake_queue(dev);
1882 break;
1884 case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
1885 ++ Intr_test_counter;
1886 break;
1888 case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */
1889 process_chdlc_exception(card);
1890 break;
1892 case GLOBAL_EXCEP_COND_APP_INT_PEND:
1893 process_global_exception(card);
1894 break;
1896 case TIMER_APP_INT_PEND:
1897 timer_intr(card);
1898 break;
1900 default:
1901 printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n",
1902 card->devname,
1903 flags->interrupt_info_struct.interrupt_type);
1904 printk(KERN_INFO "Code name: ");
1905 for(i = 0; i < 4; i ++)
1906 printk(KERN_INFO "%c",
1907 flags->global_info_struct.codename[i]);
1908 printk(KERN_INFO "\nCode version: ");
1909 for(i = 0; i < 4; i ++)
1910 printk(KERN_INFO "%c",
1911 flags->global_info_struct.codeversion[i]);
1912 printk(KERN_INFO "\n");
1913 break;
1916 isr_done:
1918 card->in_isr = 0;
1919 flags->interrupt_info_struct.interrupt_type = 0;
1920 return;
1923 /*============================================================================
1924 * Receive interrupt handler.
1926 static void rx_intr (sdla_t* card)
1928 struct net_device *dev;
1929 chdlc_private_area_t *chdlc_priv_area;
1930 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1931 CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
1932 struct sk_buff *skb;
1933 unsigned len;
1934 unsigned addr = rxbuf->ptr_data_bfr;
1935 void *buf;
1936 int i,udp_type;
1938 if (rxbuf->opp_flag != 0x01) {
1939 printk(KERN_INFO
1940 "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
1941 card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
1942 printk(KERN_INFO "Code name: ");
1943 for(i = 0; i < 4; i ++)
1944 printk(KERN_INFO "%c",
1945 flags->global_info_struct.codename[i]);
1946 printk(KERN_INFO "\nCode version: ");
1947 for(i = 0; i < 4; i ++)
1948 printk(KERN_INFO "%c",
1949 flags->global_info_struct.codeversion[i]);
1950 printk(KERN_INFO "\n");
1953 /* Bug Fix: Mar 6 2000
1954 * If we get a corrupted mailbox, it measn that driver
1955 * is out of sync with the firmware. There is no recovery.
1956 * If we don't turn off all interrupts for this card
1957 * the machine will crash.
1959 printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
1960 printk(KERN_INFO "Please contact Sangoma Technologies !\n");
1961 chdlc_set_intr_mode(card,0);
1962 return;
1965 len = rxbuf->frame_length;
1967 if (card->tty_opt){
1969 if (rxbuf->error_flag){
1970 goto rx_exit;
1973 if (len <= CRC_LENGTH){
1974 goto rx_exit;
1977 if (!card->u.c.async_mode){
1978 len -= CRC_LENGTH;
1981 wanpipe_tty_receive(card,addr,len);
1982 goto rx_exit;
1985 dev = card->wandev.dev;
1987 if (!dev){
1988 goto rx_exit;
1991 if (!netif_running(dev))
1992 goto rx_exit;
1994 chdlc_priv_area = dev->priv;
1997 /* Allocate socket buffer */
1998 skb = dev_alloc_skb(len);
2000 if (skb == NULL) {
2001 printk(KERN_INFO "%s: no socket buffers available!\n",
2002 card->devname);
2003 ++card->wandev.stats.rx_dropped;
2004 goto rx_exit;
2007 /* Copy data to the socket buffer */
2008 if((addr + len) > card->u.c.rx_top + 1) {
2009 unsigned tmp = card->u.c.rx_top - addr + 1;
2010 buf = skb_put(skb, tmp);
2011 sdla_peek(&card->hw, addr, buf, tmp);
2012 addr = card->u.c.rx_base;
2013 len -= tmp;
2016 buf = skb_put(skb, len);
2017 sdla_peek(&card->hw, addr, buf, len);
2019 skb->protocol = htons(ETH_P_IP);
2021 card->wandev.stats.rx_packets ++;
2022 card->wandev.stats.rx_bytes += skb->len;
2023 udp_type = udp_pkt_type( skb, card );
2025 if(udp_type == UDP_CPIPE_TYPE) {
2026 if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
2027 card, skb, dev, chdlc_priv_area)) {
2028 flags->interrupt_info_struct.
2029 interrupt_permission |=
2030 APP_INT_ON_TIMER;
2032 } else if(card->u.c.usedby == API) {
2034 api_rx_hdr_t* api_rx_hdr;
2035 skb_push(skb, sizeof(api_rx_hdr_t));
2036 api_rx_hdr = (api_rx_hdr_t*)&skb->data[0x00];
2037 api_rx_hdr->error_flag = rxbuf->error_flag;
2038 api_rx_hdr->time_stamp = rxbuf->time_stamp;
2040 skb->protocol = htons(PVC_PROT);
2041 skb->mac.raw = skb->data;
2042 skb->dev = dev;
2043 skb->pkt_type = WAN_PACKET_DATA;
2045 bh_enqueue(dev, skb);
2047 if (!test_and_set_bit(0,&chdlc_priv_area->tq_working))
2048 wanpipe_queue_work(&chdlc_priv_area->common.wanpipe_work);
2049 }else{
2050 /* FIXME: we should check to see if the received packet is a
2051 multicast packet so that we can increment the multicast
2052 statistic
2053 ++ chdlc_priv_area->if_stats.multicast;
2055 /* Pass it up the protocol stack */
2057 skb->dev = dev;
2058 skb->mac.raw = skb->data;
2059 netif_rx(skb);
2060 dev->last_rx = jiffies;
2063 rx_exit:
2064 /* Release buffer element and calculate a pointer to the next one */
2065 rxbuf->opp_flag = 0x00;
2066 card->u.c.rxmb = ++ rxbuf;
2067 if((void*)rxbuf > card->u.c.rxbuf_last){
2068 card->u.c.rxmb = card->u.c.rxbuf_base;
2072 /*============================================================================
2073 * Timer interrupt handler.
2074 * The timer interrupt is used for two purposes:
2075 * 1) Processing udp calls from 'cpipemon'.
2076 * 2) Reading board-level statistics for updating the proc file system.
2078 void timer_intr(sdla_t *card)
2080 struct net_device* dev;
2081 chdlc_private_area_t* chdlc_priv_area = NULL;
2082 SHARED_MEMORY_INFO_STRUCT* flags = NULL;
2084 if ((dev = card->wandev.dev)==NULL){
2085 flags = card->u.c.flags;
2086 flags->interrupt_info_struct.interrupt_permission &=
2087 ~APP_INT_ON_TIMER;
2088 return;
2091 chdlc_priv_area = dev->priv;
2093 if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) {
2094 if (!config_chdlc(card)){
2095 chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
2099 /* process a udp call if pending */
2100 if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
2101 process_udp_mgmt_pkt(card, dev,
2102 chdlc_priv_area);
2103 chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
2106 /* read the communications statistics if required */
2107 if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
2108 update_comms_stats(card, chdlc_priv_area);
2109 if(!(-- chdlc_priv_area->update_comms_stats)) {
2110 chdlc_priv_area->timer_int_enabled &=
2111 ~TMR_INT_ENABLED_UPDATE;
2115 /* only disable the timer interrupt if there are no udp or statistic */
2116 /* updates pending */
2117 if(!chdlc_priv_area->timer_int_enabled) {
2118 flags = card->u.c.flags;
2119 flags->interrupt_info_struct.interrupt_permission &=
2120 ~APP_INT_ON_TIMER;
2124 /*------------------------------------------------------------------------------
2125 Miscellaneous Functions
2126 - set_chdlc_config() used to set configuration options on the board
2127 ------------------------------------------------------------------------------*/
2129 static int set_chdlc_config(sdla_t* card)
2131 CHDLC_CONFIGURATION_STRUCT cfg;
2133 memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
2135 if(card->wandev.clocking){
2136 cfg.baud_rate = card->wandev.bps;
2139 cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
2140 INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
2142 cfg.modem_config_options = 0;
2143 cfg.modem_status_timer = 100;
2145 cfg.CHDLC_protocol_options = card->u.c.protocol_options;
2147 if (card->tty_opt){
2148 cfg.CHDLC_API_options = DISCARD_RX_ERROR_FRAMES;
2151 cfg.percent_data_buffer_for_Tx = (card->u.c.receive_only) ? 0 : 50;
2152 cfg.CHDLC_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT |
2153 CHDLC_RX_DATA_BYTE_COUNT_STAT);
2155 if (card->tty_opt){
2156 card->wandev.mtu = TTY_CHDLC_MAX_MTU;
2158 cfg.max_CHDLC_data_field_length = card->wandev.mtu;
2159 cfg.transmit_keepalive_timer = card->u.c.kpalv_tx;
2160 cfg.receive_keepalive_timer = card->u.c.kpalv_rx;
2161 cfg.keepalive_error_tolerance = card->u.c.kpalv_err;
2162 cfg.SLARP_request_timer = card->u.c.slarp_timer;
2164 if (cfg.SLARP_request_timer) {
2165 cfg.IP_address = 0;
2166 cfg.IP_netmask = 0;
2168 }else if (card->wandev.dev){
2169 struct net_device *dev = card->wandev.dev;
2170 chdlc_private_area_t *chdlc_priv_area = dev->priv;
2172 struct in_device *in_dev = dev->ip_ptr;
2174 if(in_dev != NULL) {
2175 struct in_ifaddr *ifa = in_dev->ifa_list;
2177 if (ifa != NULL ) {
2178 cfg.IP_address = ntohl(ifa->ifa_local);
2179 cfg.IP_netmask = ntohl(ifa->ifa_mask);
2180 chdlc_priv_area->IP_address = ntohl(ifa->ifa_local);
2181 chdlc_priv_area->IP_netmask = ntohl(ifa->ifa_mask);
2185 /* FIXME: We must re-think this message in next release
2186 if((cfg.IP_address & 0x000000FF) > 2) {
2187 printk(KERN_WARNING "\n");
2188 printk(KERN_WARNING " WARNING:%s configured with an\n",
2189 card->devname);
2190 printk(KERN_WARNING " invalid local IP address.\n");
2191 printk(KERN_WARNING " Slarp pragmatics will fail.\n");
2192 printk(KERN_WARNING " IP address should be of the\n");
2193 printk(KERN_WARNING " format A.B.C.1 or A.B.C.2.\n");
2198 return chdlc_configure(card, &cfg);
2202 /*-----------------------------------------------------------------------------
2203 set_asy_config() used to set asynchronous configuration options on the board
2204 ------------------------------------------------------------------------------*/
2206 static int set_asy_config(sdla_t* card)
2209 ASY_CONFIGURATION_STRUCT cfg;
2210 CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
2211 int err;
2213 memset(&cfg, 0, sizeof(ASY_CONFIGURATION_STRUCT));
2215 if(card->wandev.clocking)
2216 cfg.baud_rate = card->wandev.bps;
2218 cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
2219 INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
2221 cfg.modem_config_options = 0;
2222 cfg.asy_API_options = card->u.c.api_options;
2223 cfg.asy_protocol_options = card->u.c.protocol_options;
2224 cfg.Tx_bits_per_char = card->u.c.tx_bits_per_char;
2225 cfg.Rx_bits_per_char = card->u.c.rx_bits_per_char;
2226 cfg.stop_bits = card->u.c.stop_bits;
2227 cfg.parity = card->u.c.parity;
2228 cfg.break_timer = card->u.c.break_timer;
2229 cfg.asy_Rx_inter_char_timer = card->u.c.inter_char_timer;
2230 cfg.asy_Rx_complete_length = card->u.c.rx_complete_length;
2231 cfg.XON_char = card->u.c.xon_char;
2232 cfg.XOFF_char = card->u.c.xoff_char;
2233 cfg.asy_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT |
2234 CHDLC_RX_DATA_BYTE_COUNT_STAT);
2236 mailbox->buffer_length = sizeof(ASY_CONFIGURATION_STRUCT);
2237 memcpy(mailbox->data, &cfg, mailbox->buffer_length);
2238 mailbox->command = SET_ASY_CONFIGURATION;
2239 err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
2240 if (err != COMMAND_OK)
2241 chdlc_error (card, err, mailbox);
2242 return err;
2245 /*============================================================================
2246 * Enable asynchronous communications.
2249 static int asy_comm_enable (sdla_t* card)
2252 int err;
2253 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2255 mb->buffer_length = 0;
2256 mb->command = ENABLE_ASY_COMMUNICATIONS;
2257 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2258 if (err != COMMAND_OK && card->wandev.dev)
2259 chdlc_error(card, err, mb);
2261 if (!err)
2262 card->u.c.comm_enabled = 1;
2264 return err;
2267 /*============================================================================
2268 * Process global exception condition
2270 static int process_global_exception(sdla_t *card)
2272 CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
2273 int err;
2275 mbox->buffer_length = 0;
2276 mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
2277 err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
2279 if(err != CMD_TIMEOUT ){
2281 switch(mbox->return_code) {
2283 case EXCEP_MODEM_STATUS_CHANGE:
2285 printk(KERN_INFO "%s: Modem status change\n",
2286 card->devname);
2288 switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
2289 case (DCD_HIGH):
2290 printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname);
2291 break;
2292 case (CTS_HIGH):
2293 printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname);
2294 break;
2295 case ((DCD_HIGH | CTS_HIGH)):
2296 printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname);
2297 break;
2298 default:
2299 printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname);
2300 break;
2302 break;
2304 case EXCEP_TRC_DISABLED:
2305 printk(KERN_INFO "%s: Line trace disabled\n",
2306 card->devname);
2307 break;
2309 case EXCEP_IRQ_TIMEOUT:
2310 printk(KERN_INFO "%s: IRQ timeout occurred\n",
2311 card->devname);
2312 break;
2314 case 0x17:
2315 if (card->tty_opt){
2316 if (card->tty && card->tty_open){
2317 printk(KERN_INFO
2318 "%s: Modem Hangup Exception: Hanging Up!\n",
2319 card->devname);
2320 tty_hangup(card->tty);
2322 break;
2325 /* If TTY is not used just drop throught */
2327 default:
2328 printk(KERN_INFO "%s: Global exception %x\n",
2329 card->devname, mbox->return_code);
2330 break;
2333 return 0;
2337 /*============================================================================
2338 * Process chdlc exception condition
2340 static int process_chdlc_exception(sdla_t *card)
2342 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2343 int err;
2345 mb->buffer_length = 0;
2346 mb->command = READ_CHDLC_EXCEPTION_CONDITION;
2347 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2348 if(err != CMD_TIMEOUT) {
2350 switch (err) {
2352 case EXCEP_LINK_ACTIVE:
2353 port_set_state(card, WAN_CONNECTED);
2354 trigger_chdlc_poll(card->wandev.dev);
2355 break;
2357 case EXCEP_LINK_INACTIVE_MODEM:
2358 port_set_state(card, WAN_DISCONNECTED);
2359 unconfigure_ip(card);
2360 trigger_chdlc_poll(card->wandev.dev);
2361 break;
2363 case EXCEP_LINK_INACTIVE_KPALV:
2364 port_set_state(card, WAN_DISCONNECTED);
2365 printk(KERN_INFO "%s: Keepalive timer expired.\n",
2366 card->devname);
2367 unconfigure_ip(card);
2368 trigger_chdlc_poll(card->wandev.dev);
2369 break;
2371 case EXCEP_IP_ADDRESS_DISCOVERED:
2372 if (configure_ip(card))
2373 return -1;
2374 break;
2376 case EXCEP_LOOPBACK_CONDITION:
2377 printk(KERN_INFO "%s: Loopback Condition Detected.\n",
2378 card->devname);
2379 break;
2381 case NO_CHDLC_EXCEP_COND_TO_REPORT:
2382 printk(KERN_INFO "%s: No exceptions reported.\n",
2383 card->devname);
2384 break;
2388 return 0;
2392 /*============================================================================
2393 * Configure IP from SLARP negotiation
2394 * This adds dynamic routes when SLARP has provided valid addresses
2397 static int configure_ip (sdla_t* card)
2399 struct net_device *dev = card->wandev.dev;
2400 chdlc_private_area_t *chdlc_priv_area;
2401 char err;
2403 if (!dev)
2404 return 0;
2406 chdlc_priv_area = dev->priv;
2409 /* set to discover */
2410 if(card->u.c.slarp_timer != 0x00) {
2411 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2412 CHDLC_CONFIGURATION_STRUCT *cfg;
2414 mb->buffer_length = 0;
2415 mb->command = READ_CHDLC_CONFIGURATION;
2416 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2418 if(err != COMMAND_OK) {
2419 chdlc_error(card,err,mb);
2420 return -1;
2423 cfg = (CHDLC_CONFIGURATION_STRUCT *)mb->data;
2424 chdlc_priv_area->IP_address = cfg->IP_address;
2425 chdlc_priv_area->IP_netmask = cfg->IP_netmask;
2427 /* Set flag to add route */
2428 chdlc_priv_area->route_status = ADD_ROUTE;
2430 /* The idea here is to add the route in the poll routine.
2431 This way, we aren't in interrupt context when adding routes */
2432 trigger_chdlc_poll(dev);
2435 return 0;
2439 /*============================================================================
2440 * Un-Configure IP negotiated by SLARP
2441 * This removes dynamic routes when the link becomes inactive.
2444 static int unconfigure_ip (sdla_t* card)
2446 struct net_device *dev = card->wandev.dev;
2447 chdlc_private_area_t *chdlc_priv_area;
2449 if (!dev)
2450 return 0;
2452 chdlc_priv_area= dev->priv;
2454 if (chdlc_priv_area->route_status == ROUTE_ADDED) {
2456 /* Note: If this function is called, the
2457 * port state has been DISCONNECTED. This state
2458 * change will trigger a poll_disconnected
2459 * function, that will check for this condition.
2461 chdlc_priv_area->route_status = REMOVE_ROUTE;
2464 return 0;
2467 /*============================================================================
2468 * Routine to add/remove routes
2469 * Called like a polling routine when Routes are flagged to be added/removed.
2472 static void process_route (sdla_t *card)
2474 struct net_device *dev = card->wandev.dev;
2475 unsigned char port_num;
2476 chdlc_private_area_t *chdlc_priv_area = NULL;
2477 u32 local_IP_addr = 0;
2478 u32 remote_IP_addr = 0;
2479 u32 IP_netmask, IP_addr;
2480 int err = 0;
2481 struct in_device *in_dev;
2482 mm_segment_t fs;
2483 struct ifreq if_info;
2484 struct sockaddr_in *if_data1, *if_data2;
2486 chdlc_priv_area = dev->priv;
2487 port_num = card->u.c.comm_port;
2489 /* Bug Fix Mar 16 2000
2490 * AND the IP address to the Mask before checking
2491 * the last two bits. */
2493 if((chdlc_priv_area->route_status == ADD_ROUTE) &&
2494 ((chdlc_priv_area->IP_address & ~chdlc_priv_area->IP_netmask) > 2)) {
2496 printk(KERN_INFO "%s: Dynamic route failure.\n",card->devname);
2498 if(card->u.c.slarp_timer) {
2499 u32 addr_net = htonl(chdlc_priv_area->IP_address);
2501 printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u received\n",
2502 card->devname,
2503 NIPQUAD(addr_net));
2504 printk(KERN_INFO "%s: from remote station.\n",
2505 card->devname);
2507 }else{
2508 u32 addr_net = htonl(chdlc_priv_area->IP_address);
2510 printk(KERN_INFO "%s: Bad IP address %u.%u.%u.%u issued\n",
2511 card->devname,
2512 NIPQUAD(addr_net));
2513 printk(KERN_INFO "%s: to remote station. Local\n",
2514 card->devname);
2515 printk(KERN_INFO "%s: IP address must be A.B.C.1\n",
2516 card->devname);
2517 printk(KERN_INFO "%s: or A.B.C.2.\n",card->devname);
2520 /* remove the route due to the IP address error condition */
2521 chdlc_priv_area->route_status = REMOVE_ROUTE;
2522 err = 1;
2525 /* If we are removing a route with bad IP addressing, then use the */
2526 /* locally configured IP addresses */
2527 if((chdlc_priv_area->route_status == REMOVE_ROUTE) && err) {
2529 /* do not remove a bad route that has already been removed */
2530 if(chdlc_priv_area->route_removed) {
2531 return;
2534 in_dev = dev->ip_ptr;
2536 if(in_dev != NULL) {
2537 struct in_ifaddr *ifa = in_dev->ifa_list;
2538 if (ifa != NULL ) {
2539 local_IP_addr = ifa->ifa_local;
2540 IP_netmask = ifa->ifa_mask;
2543 }else{
2544 /* According to Cisco HDLC, if the point-to-point address is
2545 A.B.C.1, then we are the opposite (A.B.C.2), and vice-versa.
2547 IP_netmask = ntohl(chdlc_priv_area->IP_netmask);
2548 remote_IP_addr = ntohl(chdlc_priv_area->IP_address);
2551 /* If Netmask is 255.255.255.255 the local address
2552 * calculation will fail. Default it back to 255.255.255.0 */
2553 if (IP_netmask == 0xffffffff)
2554 IP_netmask &= 0x00ffffff;
2556 /* Bug Fix Mar 16 2000
2557 * AND the Remote IP address with IP netmask, instead
2558 * of static netmask of 255.255.255.0 */
2559 local_IP_addr = (remote_IP_addr & IP_netmask) +
2560 (~remote_IP_addr & ntohl(0x0003));
2562 if(!card->u.c.slarp_timer) {
2563 IP_addr = local_IP_addr;
2564 local_IP_addr = remote_IP_addr;
2565 remote_IP_addr = IP_addr;
2569 fs = get_fs(); /* Save file system */
2570 set_fs(get_ds()); /* Get user space block */
2572 /* Setup a structure for adding/removing routes */
2573 memset(&if_info, 0, sizeof(if_info));
2574 strcpy(if_info.ifr_name, dev->name);
2576 switch (chdlc_priv_area->route_status) {
2578 case ADD_ROUTE:
2580 if(!card->u.c.slarp_timer) {
2581 if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2582 if_data2->sin_addr.s_addr = remote_IP_addr;
2583 if_data2->sin_family = AF_INET;
2584 err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2585 } else {
2586 if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
2587 if_data1->sin_addr.s_addr = local_IP_addr;
2588 if_data1->sin_family = AF_INET;
2589 if(!(err = devinet_ioctl(SIOCSIFADDR, &if_info))){
2590 if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2591 if_data2->sin_addr.s_addr = remote_IP_addr;
2592 if_data2->sin_family = AF_INET;
2593 err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2597 if(err) {
2598 printk(KERN_INFO "%s: Add route %u.%u.%u.%u failed (%d)\n",
2599 card->devname, NIPQUAD(remote_IP_addr), err);
2600 } else {
2601 ((chdlc_private_area_t *)dev->priv)->route_status = ROUTE_ADDED;
2602 printk(KERN_INFO "%s: Dynamic route added.\n",
2603 card->devname);
2604 printk(KERN_INFO "%s: Local IP addr : %u.%u.%u.%u\n",
2605 card->devname, NIPQUAD(local_IP_addr));
2606 printk(KERN_INFO "%s: Remote IP addr: %u.%u.%u.%u\n",
2607 card->devname, NIPQUAD(remote_IP_addr));
2608 chdlc_priv_area->route_removed = 0;
2610 break;
2613 case REMOVE_ROUTE:
2615 /* Change the local ip address of the interface to 0.
2616 * This will also delete the destination route.
2618 if(!card->u.c.slarp_timer) {
2619 if_data2 = (struct sockaddr_in *)&if_info.ifr_dstaddr;
2620 if_data2->sin_addr.s_addr = 0;
2621 if_data2->sin_family = AF_INET;
2622 err = devinet_ioctl(SIOCSIFDSTADDR, &if_info);
2623 } else {
2624 if_data1 = (struct sockaddr_in *)&if_info.ifr_addr;
2625 if_data1->sin_addr.s_addr = 0;
2626 if_data1->sin_family = AF_INET;
2627 err = devinet_ioctl(SIOCSIFADDR,&if_info);
2630 if(err) {
2631 printk(KERN_INFO
2632 "%s: Remove route %u.%u.%u.%u failed, (err %d)\n",
2633 card->devname, NIPQUAD(remote_IP_addr),
2634 err);
2635 } else {
2636 ((chdlc_private_area_t *)dev->priv)->route_status =
2637 NO_ROUTE;
2638 printk(KERN_INFO "%s: Dynamic route removed: %u.%u.%u.%u\n",
2639 card->devname, NIPQUAD(local_IP_addr));
2640 chdlc_priv_area->route_removed = 1;
2642 break;
2645 set_fs(fs); /* Restore file system */
2650 /*=============================================================================
2651 * Store a UDP management packet for later processing.
2654 static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
2655 struct sk_buff *skb, struct net_device* dev,
2656 chdlc_private_area_t* chdlc_priv_area)
2658 int udp_pkt_stored = 0;
2660 if(!chdlc_priv_area->udp_pkt_lgth &&
2661 (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
2662 chdlc_priv_area->udp_pkt_lgth = skb->len;
2663 chdlc_priv_area->udp_pkt_src = udp_pkt_src;
2664 memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
2665 chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
2666 udp_pkt_stored = 1;
2669 if(udp_pkt_src == UDP_PKT_FRM_STACK){
2670 dev_kfree_skb_any(skb);
2671 }else{
2672 dev_kfree_skb_any(skb);
2675 return(udp_pkt_stored);
2679 /*=============================================================================
2680 * Process UDP management packet.
2683 static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
2684 chdlc_private_area_t* chdlc_priv_area )
2686 unsigned char *buf;
2687 unsigned int frames, len;
2688 struct sk_buff *new_skb;
2689 unsigned short buffer_length, real_len;
2690 unsigned long data_ptr;
2691 unsigned data_length;
2692 int udp_mgmt_req_valid = 1;
2693 CHDLC_MAILBOX_STRUCT *mb = card->mbox;
2694 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
2695 chdlc_udp_pkt_t *chdlc_udp_pkt;
2696 struct timeval tv;
2697 int err;
2698 char ut_char;
2700 chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
2702 if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
2704 /* Only these commands are support for remote debugging.
2705 * All others are not */
2706 switch(chdlc_udp_pkt->cblock.command) {
2708 case READ_GLOBAL_STATISTICS:
2709 case READ_MODEM_STATUS:
2710 case READ_CHDLC_LINK_STATUS:
2711 case CPIPE_ROUTER_UP_TIME:
2712 case READ_COMMS_ERROR_STATS:
2713 case READ_CHDLC_OPERATIONAL_STATS:
2715 /* These two commands are executed for
2716 * each request */
2717 case READ_CHDLC_CONFIGURATION:
2718 case READ_CHDLC_CODE_VERSION:
2719 udp_mgmt_req_valid = 1;
2720 break;
2721 default:
2722 udp_mgmt_req_valid = 0;
2723 break;
2727 if(!udp_mgmt_req_valid) {
2729 /* set length to 0 */
2730 chdlc_udp_pkt->cblock.buffer_length = 0;
2732 /* set return code */
2733 chdlc_udp_pkt->cblock.return_code = 0xCD;
2735 if (net_ratelimit()){
2736 printk(KERN_INFO
2737 "%s: Warning, Illegal UDP command attempted from network: %x\n",
2738 card->devname,chdlc_udp_pkt->cblock.command);
2741 } else {
2742 unsigned long trace_status_cfg_addr = 0;
2743 TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
2744 TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
2746 switch(chdlc_udp_pkt->cblock.command) {
2748 case CPIPE_ENABLE_TRACING:
2749 if (!chdlc_priv_area->TracingEnabled) {
2751 /* OPERATE_DATALINE_MONITOR */
2753 mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
2754 mb->command = SET_TRACE_CONFIGURATION;
2756 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
2757 trace_config = TRACE_ACTIVE;
2758 /* Trace delay mode is not used because it slows
2759 down transfer and results in a standoff situation
2760 when there is a lot of data */
2762 /* Configure the Trace based on user inputs */
2763 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |=
2764 chdlc_udp_pkt->data[0];
2766 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
2767 trace_deactivation_timer = 4000;
2770 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2771 if (err != COMMAND_OK) {
2772 chdlc_error(card,err,mb);
2773 card->TracingEnabled = 0;
2774 chdlc_udp_pkt->cblock.return_code = err;
2775 mb->buffer_length = 0;
2776 break;
2779 /* Get the base address of the trace element list */
2780 mb->buffer_length = 0;
2781 mb->command = READ_TRACE_CONFIGURATION;
2782 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2784 if (err != COMMAND_OK) {
2785 chdlc_error(card,err,mb);
2786 chdlc_priv_area->TracingEnabled = 0;
2787 chdlc_udp_pkt->cblock.return_code = err;
2788 mb->buffer_length = 0;
2789 break;
2792 trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
2793 mb->data) -> ptr_trace_stat_el_cfg_struct;
2795 sdla_peek(&card->hw, trace_status_cfg_addr,
2796 &trace_cfg_struct, sizeof(trace_cfg_struct));
2798 chdlc_priv_area->start_trace_addr = trace_cfg_struct.
2799 base_addr_trace_status_elements;
2801 chdlc_priv_area->number_trace_elements =
2802 trace_cfg_struct.number_trace_status_elements;
2804 chdlc_priv_area->end_trace_addr = (unsigned long)
2805 ((TRACE_STATUS_ELEMENT_STRUCT *)
2806 chdlc_priv_area->start_trace_addr +
2807 (chdlc_priv_area->number_trace_elements - 1));
2809 chdlc_priv_area->base_addr_trace_buffer =
2810 trace_cfg_struct.base_addr_trace_buffer;
2812 chdlc_priv_area->end_addr_trace_buffer =
2813 trace_cfg_struct.end_addr_trace_buffer;
2815 chdlc_priv_area->curr_trace_addr =
2816 trace_cfg_struct.next_trace_element_to_use;
2818 chdlc_priv_area->available_buffer_space = 2000 -
2819 sizeof(ip_pkt_t) -
2820 sizeof(udp_pkt_t) -
2821 sizeof(wp_mgmt_t) -
2822 sizeof(cblock_t) -
2823 sizeof(trace_info_t);
2825 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2826 mb->buffer_length = 0;
2827 chdlc_priv_area->TracingEnabled = 1;
2828 break;
2831 case CPIPE_DISABLE_TRACING:
2832 if (chdlc_priv_area->TracingEnabled) {
2834 /* OPERATE_DATALINE_MONITOR */
2835 mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
2836 mb->command = SET_TRACE_CONFIGURATION;
2837 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
2838 trace_config = TRACE_INACTIVE;
2839 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2842 chdlc_priv_area->TracingEnabled = 0;
2843 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2844 mb->buffer_length = 0;
2845 break;
2848 case CPIPE_GET_TRACE_INFO:
2850 if (!chdlc_priv_area->TracingEnabled) {
2851 chdlc_udp_pkt->cblock.return_code = 1;
2852 mb->buffer_length = 0;
2853 break;
2856 chdlc_udp_pkt->trace_info.ismoredata = 0x00;
2857 buffer_length = 0; /* offset of packet already occupied */
2859 for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
2861 trace_pkt_t *trace_pkt = (trace_pkt_t *)
2862 &chdlc_udp_pkt->data[buffer_length];
2864 sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
2865 (unsigned char *)&trace_element_struct,
2866 sizeof(TRACE_STATUS_ELEMENT_STRUCT));
2868 if (trace_element_struct.opp_flag == 0x00) {
2869 break;
2872 /* get pointer to real data */
2873 data_ptr = trace_element_struct.ptr_data_bfr;
2875 /* See if there is actual data on the trace buffer */
2876 if (data_ptr){
2877 data_length = trace_element_struct.trace_length;
2878 }else{
2879 data_length = 0;
2880 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2883 if( (chdlc_priv_area->available_buffer_space - buffer_length)
2884 < ( sizeof(trace_pkt_t) + data_length) ) {
2886 /* indicate there are more frames on board & exit */
2887 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2888 break;
2891 trace_pkt->status = trace_element_struct.trace_type;
2893 trace_pkt->time_stamp =
2894 trace_element_struct.trace_time_stamp;
2896 trace_pkt->real_length =
2897 trace_element_struct.trace_length;
2899 /* see if we can fit the frame into the user buffer */
2900 real_len = trace_pkt->real_length;
2902 if (data_ptr == 0) {
2903 trace_pkt->data_avail = 0x00;
2904 } else {
2905 unsigned tmp = 0;
2907 /* get the data from circular buffer
2908 must check for end of buffer */
2909 trace_pkt->data_avail = 0x01;
2911 if ((data_ptr + real_len) >
2912 chdlc_priv_area->end_addr_trace_buffer + 1){
2914 tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
2915 sdla_peek(&card->hw, data_ptr,
2916 trace_pkt->data,tmp);
2917 data_ptr = chdlc_priv_area->base_addr_trace_buffer;
2920 sdla_peek(&card->hw, data_ptr,
2921 &trace_pkt->data[tmp], real_len - tmp);
2924 /* zero the opp flag to show we got the frame */
2925 ut_char = 0x00;
2926 sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
2928 /* now move onto the next frame */
2929 chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
2931 /* check if we went over the last address */
2932 if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
2933 chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
2936 if(trace_pkt->data_avail == 0x01) {
2937 buffer_length += real_len - 1;
2940 /* for the header */
2941 buffer_length += sizeof(trace_pkt_t);
2943 } /* For Loop */
2945 if (frames == chdlc_priv_area->number_trace_elements){
2946 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
2948 chdlc_udp_pkt->trace_info.num_frames = frames;
2950 mb->buffer_length = buffer_length;
2951 chdlc_udp_pkt->cblock.buffer_length = buffer_length;
2953 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2955 break;
2958 case CPIPE_FT1_READ_STATUS:
2959 ((unsigned char *)chdlc_udp_pkt->data )[0] =
2960 flags->FT1_info_struct.parallel_port_A_input;
2962 ((unsigned char *)chdlc_udp_pkt->data )[1] =
2963 flags->FT1_info_struct.parallel_port_B_input;
2965 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2966 chdlc_udp_pkt->cblock.buffer_length = 2;
2967 mb->buffer_length = 2;
2968 break;
2970 case CPIPE_ROUTER_UP_TIME:
2971 do_gettimeofday( &tv );
2972 chdlc_priv_area->router_up_time = tv.tv_sec -
2973 chdlc_priv_area->router_start_time;
2974 *(unsigned long *)&chdlc_udp_pkt->data =
2975 chdlc_priv_area->router_up_time;
2976 mb->buffer_length = sizeof(unsigned long);
2977 chdlc_udp_pkt->cblock.buffer_length = sizeof(unsigned long);
2978 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
2979 break;
2981 case FT1_MONITOR_STATUS_CTRL:
2982 /* Enable FT1 MONITOR STATUS */
2983 if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||
2984 (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
2986 if( rCount++ != 0 ) {
2987 chdlc_udp_pkt->cblock.
2988 return_code = COMMAND_OK;
2989 mb->buffer_length = 1;
2990 break;
2994 /* Disable FT1 MONITOR STATUS */
2995 if( chdlc_udp_pkt->data[0] == 0) {
2997 if( --rCount != 0) {
2998 chdlc_udp_pkt->cblock.
2999 return_code = COMMAND_OK;
3000 mb->buffer_length = 1;
3001 break;
3004 goto dflt_1;
3006 default:
3007 dflt_1:
3008 /* it's a board command */
3009 mb->command = chdlc_udp_pkt->cblock.command;
3010 mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
3011 if (mb->buffer_length) {
3012 memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
3013 data, mb->buffer_length);
3015 /* run the command on the board */
3016 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
3017 if (err != COMMAND_OK) {
3018 break;
3021 /* copy the result back to our buffer */
3022 memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t));
3024 if (mb->buffer_length) {
3025 memcpy(&chdlc_udp_pkt->data, &mb->data,
3026 mb->buffer_length);
3029 } /* end of switch */
3030 } /* end of else */
3032 /* Fill UDP TTL */
3033 chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
3035 len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
3038 if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK){
3040 /* Must check if we interrupted if_send() routine. The
3041 * tx buffers might be used. If so drop the packet */
3042 if (!test_bit(SEND_CRIT,&card->wandev.critical)) {
3044 if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
3045 ++ card->wandev.stats.tx_packets;
3046 card->wandev.stats.tx_bytes += len;
3049 } else {
3051 /* Pass it up the stack
3052 Allocate socket buffer */
3053 if ((new_skb = dev_alloc_skb(len)) != NULL) {
3054 /* copy data into new_skb */
3056 buf = skb_put(new_skb, len);
3057 memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
3059 /* Decapsulate pkt and pass it up the protocol stack */
3060 new_skb->protocol = htons(ETH_P_IP);
3061 new_skb->dev = dev;
3062 new_skb->mac.raw = new_skb->data;
3064 netif_rx(new_skb);
3065 dev->last_rx = jiffies;
3066 } else {
3068 printk(KERN_INFO "%s: no socket buffers available!\n",
3069 card->devname);
3073 chdlc_priv_area->udp_pkt_lgth = 0;
3075 return 0;
3078 /*============================================================================
3079 * Initialize Receive and Transmit Buffers.
3082 static void init_chdlc_tx_rx_buff( sdla_t* card)
3084 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
3085 CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
3086 CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
3087 char err;
3089 mb->buffer_length = 0;
3090 mb->command = READ_CHDLC_CONFIGURATION;
3091 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
3093 if(err != COMMAND_OK) {
3094 if (card->wandev.dev){
3095 chdlc_error(card,err,mb);
3097 return;
3100 if(card->hw.type == SDLA_S514) {
3101 tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
3102 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
3103 ptr_CHDLC_Tx_stat_el_cfg_struct));
3104 rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
3105 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
3106 ptr_CHDLC_Rx_stat_el_cfg_struct));
3108 /* Setup Head and Tails for buffers */
3109 card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
3110 tx_config->base_addr_Tx_status_elements);
3111 card->u.c.txbuf_last =
3112 (CHDLC_DATA_TX_STATUS_EL_STRUCT *)
3113 card->u.c.txbuf_base +
3114 (tx_config->number_Tx_status_elements - 1);
3116 card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
3117 rx_config->base_addr_Rx_status_elements);
3118 card->u.c.rxbuf_last =
3119 (CHDLC_DATA_RX_STATUS_EL_STRUCT *)
3120 card->u.c.rxbuf_base +
3121 (rx_config->number_Rx_status_elements - 1);
3123 /* Set up next pointer to be used */
3124 card->u.c.txbuf = (void *)(card->hw.dpmbase +
3125 tx_config->next_Tx_status_element_to_use);
3126 card->u.c.rxmb = (void *)(card->hw.dpmbase +
3127 rx_config->next_Rx_status_element_to_use);
3129 else {
3130 tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
3131 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
3132 ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
3134 rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
3135 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
3136 ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
3138 /* Setup Head and Tails for buffers */
3139 card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
3140 (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
3141 card->u.c.txbuf_last =
3142 (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
3143 + (tx_config->number_Tx_status_elements - 1);
3144 card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
3145 (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
3146 card->u.c.rxbuf_last =
3147 (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
3148 + (rx_config->number_Rx_status_elements - 1);
3150 /* Set up next pointer to be used */
3151 card->u.c.txbuf = (void *)(card->hw.dpmbase +
3152 (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
3153 card->u.c.rxmb = (void *)(card->hw.dpmbase +
3154 (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
3157 /* Setup Actual Buffer Start and end addresses */
3158 card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
3159 card->u.c.rx_top = rx_config->end_addr_Rx_buffer;
3163 /*=============================================================================
3164 * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
3165 * _TEST_COUNTER times.
3167 static int intr_test( sdla_t* card)
3169 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
3170 int err,i;
3172 Intr_test_counter = 0;
3174 err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
3176 if (err == CMD_OK) {
3177 for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {
3178 mb->buffer_length = 0;
3179 mb->command = READ_CHDLC_CODE_VERSION;
3180 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
3181 if (err != CMD_OK)
3182 chdlc_error(card, err, mb);
3185 else {
3186 return err;
3189 err = chdlc_set_intr_mode(card, 0);
3191 if (err != CMD_OK)
3192 return err;
3194 return 0;
3197 /*==============================================================================
3198 * Determine what type of UDP call it is. CPIPEAB ?
3200 static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
3202 chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
3204 #ifdef _WAN_UDP_DEBUG
3205 printk(KERN_INFO "SIG %s = %s\n\
3206 UPP %x = %x\n\
3207 PRT %x = %x\n\
3208 REQ %i = %i\n\
3209 36 th = %x 37th = %x\n",
3210 chdlc_udp_pkt->wp_mgmt.signature,
3211 UDPMGMT_SIGNATURE,
3212 chdlc_udp_pkt->udp_pkt.udp_dst_port,
3213 ntohs(card->wandev.udp_port),
3214 chdlc_udp_pkt->ip_pkt.protocol,
3215 UDPMGMT_UDP_PROTOCOL,
3216 chdlc_udp_pkt->wp_mgmt.request_reply,
3217 UDPMGMT_REQUEST,
3218 skb->data[36], skb->data[37]);
3219 #endif
3221 if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
3222 (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
3223 (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
3224 (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
3226 return UDP_CPIPE_TYPE;
3228 }else{
3229 return UDP_INVALID_TYPE;
3233 /*============================================================================
3234 * Set PORT state.
3236 static void port_set_state (sdla_t *card, int state)
3238 if (card->u.c.state != state)
3240 switch (state)
3242 case WAN_CONNECTED:
3243 printk (KERN_INFO "%s: Link connected!\n",
3244 card->devname);
3245 break;
3247 case WAN_CONNECTING:
3248 printk (KERN_INFO "%s: Link connecting...\n",
3249 card->devname);
3250 break;
3252 case WAN_DISCONNECTED:
3253 printk (KERN_INFO "%s: Link disconnected!\n",
3254 card->devname);
3255 break;
3258 card->wandev.state = card->u.c.state = state;
3259 if (card->wandev.dev){
3260 struct net_device *dev = card->wandev.dev;
3261 chdlc_private_area_t *chdlc_priv_area = dev->priv;
3262 chdlc_priv_area->common.state = state;
3267 /*===========================================================================
3268 * config_chdlc
3270 * Configure the chdlc protocol and enable communications.
3272 * The if_open() function binds this function to the poll routine.
3273 * Therefore, this function will run every time the chdlc interface
3274 * is brought up. We cannot run this function from the if_open
3275 * because if_open does not have access to the remote IP address.
3277 * If the communications are not enabled, proceed to configure
3278 * the card and enable communications.
3280 * If the communications are enabled, it means that the interface
3281 * was shutdown by ether the user or driver. In this case, we
3282 * have to check that the IP addresses have not changed. If
3283 * the IP addresses have changed, we have to reconfigure the firmware
3284 * and update the changed IP addresses. Otherwise, just exit.
3288 static int config_chdlc (sdla_t *card)
3290 struct net_device *dev = card->wandev.dev;
3291 chdlc_private_area_t *chdlc_priv_area = dev->priv;
3292 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
3294 if (card->u.c.comm_enabled){
3296 /* Jun 20. 2000: NC
3297 * IP addresses are not used in the API mode */
3299 if ((chdlc_priv_area->ip_local_tmp != chdlc_priv_area->ip_local ||
3300 chdlc_priv_area->ip_remote_tmp != chdlc_priv_area->ip_remote) &&
3301 card->u.c.usedby == WANPIPE) {
3303 /* The IP addersses have changed, we must
3304 * stop the communications and reconfigure
3305 * the card. Reason: the firmware must know
3306 * the local and remote IP addresses. */
3307 disable_comm(card);
3308 port_set_state(card, WAN_DISCONNECTED);
3309 printk(KERN_INFO
3310 "%s: IP addresses changed!\n",
3311 card->devname);
3312 printk(KERN_INFO
3313 "%s: Restarting communications ...\n",
3314 card->devname);
3315 }else{
3316 /* IP addresses are the same and the link is up,
3317 * we don't have to do anything here. Therefore, exit */
3318 return 0;
3322 chdlc_priv_area->ip_local = chdlc_priv_area->ip_local_tmp;
3323 chdlc_priv_area->ip_remote = chdlc_priv_area->ip_remote_tmp;
3326 /* Setup the Board for asynchronous mode */
3327 if (card->u.c.async_mode){
3329 if (set_asy_config(card)) {
3330 printk (KERN_INFO "%s: Failed CHDLC Async configuration!\n",
3331 card->devname);
3332 return 0;
3334 }else{
3335 /* Setup the Board for CHDLC */
3336 if (set_chdlc_config(card)) {
3337 printk (KERN_INFO "%s: Failed CHDLC configuration!\n",
3338 card->devname);
3339 return 0;
3343 /* Set interrupt mode and mask */
3344 if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
3345 APP_INT_ON_GLOBAL_EXCEP_COND |
3346 APP_INT_ON_TX_FRAME |
3347 APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
3348 printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
3349 card->devname);
3350 return 0;
3354 /* Mask the Transmit and Timer interrupt */
3355 flags->interrupt_info_struct.interrupt_permission &=
3356 ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
3358 /* In TTY mode, receive interrupt will be enabled during
3359 * wanpipe_tty_open() operation */
3360 if (card->tty_opt){
3361 flags->interrupt_info_struct.interrupt_permission &= ~APP_INT_ON_RX_FRAME;
3364 /* Enable communications */
3365 if (card->u.c.async_mode){
3366 if (asy_comm_enable(card) != 0) {
3367 printk(KERN_INFO "%s: Failed to enable async commnunication!\n",
3368 card->devname);
3369 flags->interrupt_info_struct.interrupt_permission = 0;
3370 card->u.c.comm_enabled=0;
3371 chdlc_set_intr_mode(card,0);
3372 return 0;
3374 }else{
3375 if (chdlc_comm_enable(card) != 0) {
3376 printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
3377 card->devname);
3378 flags->interrupt_info_struct.interrupt_permission = 0;
3379 card->u.c.comm_enabled=0;
3380 chdlc_set_intr_mode(card,0);
3381 return 0;
3385 /* Initialize Rx/Tx buffer control fields */
3386 init_chdlc_tx_rx_buff(card);
3387 port_set_state(card, WAN_CONNECTING);
3388 return 0;
3392 /*============================================================
3393 * chdlc_poll
3395 * Rationale:
3396 * We cannot manipulate the routing tables, or
3397 * ip addresses withing the interrupt. Therefore
3398 * we must perform such actons outside an interrupt
3399 * at a later time.
3401 * Description:
3402 * CHDLC polling routine, responsible for
3403 * shutting down interfaces upon disconnect
3404 * and adding/removing routes.
3406 * Usage:
3407 * This function is executed for each CHDLC
3408 * interface through a tq_schedule bottom half.
3410 * trigger_chdlc_poll() function is used to kick
3411 * the chldc_poll routine.
3414 static void chdlc_poll(struct net_device *dev)
3416 chdlc_private_area_t *chdlc_priv_area;
3417 sdla_t *card;
3418 u8 check_gateway=0;
3419 SHARED_MEMORY_INFO_STRUCT* flags;
3422 if (!dev || (chdlc_priv_area=dev->priv) == NULL)
3423 return;
3425 card = chdlc_priv_area->card;
3426 flags = card->u.c.flags;
3428 /* (Re)Configuraiton is in progress, stop what you are
3429 * doing and get out */
3430 if (test_bit(PERI_CRIT,&card->wandev.critical)){
3431 clear_bit(POLL_CRIT,&card->wandev.critical);
3432 return;
3435 /* if_open() function has triggered the polling routine
3436 * to determine the configured IP addresses. Once the
3437 * addresses are found, trigger the chdlc configuration */
3438 if (test_bit(0,&chdlc_priv_area->config_chdlc)){
3440 chdlc_priv_area->ip_local_tmp = get_ip_address(dev,WAN_LOCAL_IP);
3441 chdlc_priv_area->ip_remote_tmp = get_ip_address(dev,WAN_POINTOPOINT_IP);
3443 /* Jun 20. 2000 Bug Fix
3444 * Only perform this check in WANPIPE mode, since
3445 * IP addresses are not used in the API mode. */
3447 if (chdlc_priv_area->ip_local_tmp == chdlc_priv_area->ip_remote_tmp &&
3448 card->u.c.slarp_timer == 0x00 &&
3449 !card->u.c.backup &&
3450 card->u.c.usedby == WANPIPE){
3452 if (++chdlc_priv_area->ip_error > MAX_IP_ERRORS){
3453 printk(KERN_INFO "\n%s: --- WARNING ---\n",
3454 card->devname);
3455 printk(KERN_INFO
3456 "%s: The local IP address is the same as the\n",
3457 card->devname);
3458 printk(KERN_INFO
3459 "%s: Point-to-Point IP address.\n",
3460 card->devname);
3461 printk(KERN_INFO "%s: --- WARNING ---\n\n",
3462 card->devname);
3463 }else{
3464 clear_bit(POLL_CRIT,&card->wandev.critical);
3465 chdlc_priv_area->poll_delay_timer.expires = jiffies+HZ;
3466 add_timer(&chdlc_priv_area->poll_delay_timer);
3467 return;
3471 clear_bit(0,&chdlc_priv_area->config_chdlc);
3472 clear_bit(POLL_CRIT,&card->wandev.critical);
3474 chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
3475 flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
3476 return;
3478 /* Dynamic interface implementation, as well as dynamic
3479 * routing. */
3481 switch (card->u.c.state){
3483 case WAN_DISCONNECTED:
3485 /* If the dynamic interface configuration is on, and interface
3486 * is up, then bring down the netowrk interface */
3488 if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) &&
3489 !test_bit(DEV_DOWN, &chdlc_priv_area->interface_down) &&
3490 card->wandev.dev->flags & IFF_UP){
3492 printk(KERN_INFO "%s: Interface %s down.\n",
3493 card->devname,card->wandev.dev->name);
3494 change_dev_flags(card->wandev.dev,(card->wandev.dev->flags&~IFF_UP));
3495 set_bit(DEV_DOWN,&chdlc_priv_area->interface_down);
3496 chdlc_priv_area->route_status = NO_ROUTE;
3498 }else{
3499 /* We need to check if the local IP address is
3500 * zero. If it is, we shouldn't try to remove it.
3503 if (card->wandev.dev->flags & IFF_UP &&
3504 get_ip_address(card->wandev.dev,WAN_LOCAL_IP) &&
3505 chdlc_priv_area->route_status != NO_ROUTE &&
3506 card->u.c.slarp_timer){
3508 process_route(card);
3511 break;
3513 case WAN_CONNECTED:
3515 /* In SMP machine this code can execute before the interface
3516 * comes up. In this case, we must make sure that we do not
3517 * try to bring up the interface before dev_open() is finished */
3520 /* DEV_DOWN will be set only when we bring down the interface
3521 * for the very first time. This way we know that it was us
3522 * that brought the interface down */
3524 if (test_bit(DYN_OPT_ON,&chdlc_priv_area->interface_down) &&
3525 test_bit(DEV_DOWN, &chdlc_priv_area->interface_down) &&
3526 !(card->wandev.dev->flags & IFF_UP)){
3528 printk(KERN_INFO "%s: Interface %s up.\n",
3529 card->devname,card->wandev.dev->name);
3530 change_dev_flags(card->wandev.dev,(card->wandev.dev->flags|IFF_UP));
3531 clear_bit(DEV_DOWN,&chdlc_priv_area->interface_down);
3532 check_gateway=1;
3535 if (chdlc_priv_area->route_status == ADD_ROUTE &&
3536 card->u.c.slarp_timer){
3538 process_route(card);
3539 check_gateway=1;
3542 if (chdlc_priv_area->gateway && check_gateway)
3543 add_gateway(card,dev);
3545 break;
3548 clear_bit(POLL_CRIT,&card->wandev.critical);
3551 /*============================================================
3552 * trigger_chdlc_poll
3554 * Description:
3555 * Add a chdlc_poll() work entry into the keventd work queue
3556 * for a specific dlci/interface. This will kick
3557 * the fr_poll() routine at a later time.
3559 * Usage:
3560 * Interrupts use this to defer a taks to
3561 * a polling routine.
3564 static void trigger_chdlc_poll(struct net_device *dev)
3566 chdlc_private_area_t *chdlc_priv_area;
3567 sdla_t *card;
3569 if (!dev)
3570 return;
3572 if ((chdlc_priv_area = dev->priv)==NULL)
3573 return;
3575 card = chdlc_priv_area->card;
3577 if (test_and_set_bit(POLL_CRIT,&card->wandev.critical)){
3578 return;
3580 if (test_bit(PERI_CRIT,&card->wandev.critical)){
3581 return;
3583 schedule_work(&chdlc_priv_area->poll_work);
3587 static void chdlc_poll_delay (unsigned long dev_ptr)
3589 struct net_device *dev = (struct net_device *)dev_ptr;
3590 trigger_chdlc_poll(dev);
3594 void s508_lock (sdla_t *card, unsigned long *smp_flags)
3596 spin_lock_irqsave(&card->wandev.lock, *smp_flags);
3597 if (card->next){
3598 spin_lock(&card->next->wandev.lock);
3602 void s508_unlock (sdla_t *card, unsigned long *smp_flags)
3604 if (card->next){
3605 spin_unlock(&card->next->wandev.lock);
3607 spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
3610 //*********** TTY SECTION ****************
3612 static void wanpipe_tty_trigger_tx_irq(sdla_t *card)
3614 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
3615 INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
3616 chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
3619 static void wanpipe_tty_trigger_poll(sdla_t *card)
3621 schedule_work(&card->tty_work);
3624 static void tty_poll_work (void* data)
3626 sdla_t *card = (sdla_t*)data;
3627 struct tty_struct *tty;
3629 if ((tty=card->tty)==NULL)
3630 return;
3632 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
3633 tty->ldisc.write_wakeup){
3634 (tty->ldisc.write_wakeup)(tty);
3636 wake_up_interruptible(&tty->write_wait);
3637 #if defined(SERIAL_HAVE_POLL_WAIT)
3638 wake_up_interruptible(&tty->poll_wait);
3639 #endif
3640 return;
3643 static void wanpipe_tty_close(struct tty_struct *tty, struct file * filp)
3645 sdla_t *card;
3646 unsigned long smp_flags;
3648 if (!tty || !tty->driver_data){
3649 return;
3652 card = (sdla_t*)tty->driver_data;
3654 if (!card)
3655 return;
3657 printk(KERN_INFO "%s: Closing TTY Driver!\n",
3658 card->devname);
3660 /* Sanity Check */
3661 if (!card->tty_open)
3662 return;
3664 wanpipe_close(card);
3665 if (--card->tty_open == 0){
3667 lock_adapter_irq(&card->wandev.lock,&smp_flags);
3668 card->tty=NULL;
3669 chdlc_disable_comm_shutdown(card);
3670 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
3672 if (card->tty_buf){
3673 kfree(card->tty_buf);
3674 card->tty_buf=NULL;
3677 if (card->tty_rx){
3678 kfree(card->tty_rx);
3679 card->tty_rx=NULL;
3682 return;
3684 static int wanpipe_tty_open(struct tty_struct *tty, struct file * filp)
3686 unsigned long smp_flags;
3687 sdla_t *card;
3689 if (!tty){
3690 return -ENODEV;
3693 if (!tty->driver_data){
3694 int port;
3695 port = tty->index;
3696 if ((port < 0) || (port >= NR_PORTS))
3697 return -ENODEV;
3699 tty->driver_data = WAN_CARD(port);
3700 if (!tty->driver_data)
3701 return -ENODEV;
3704 card = (sdla_t*)tty->driver_data;
3706 if (!card){
3707 lock_adapter_irq(&card->wandev.lock,&smp_flags);
3708 card->tty=NULL;
3709 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
3710 return -ENODEV;
3713 printk(KERN_INFO "%s: Opening TTY Driver!\n",
3714 card->devname);
3716 if (card->tty_open == 0){
3717 lock_adapter_irq(&card->wandev.lock,&smp_flags);
3718 card->tty=tty;
3719 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
3721 if (!card->tty_buf){
3722 card->tty_buf = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL);
3723 if (!card->tty_buf){
3724 card->tty_buf=NULL;
3725 card->tty=NULL;
3726 return -ENOMEM;
3730 if (!card->tty_rx){
3731 card->tty_rx = kmalloc(TTY_CHDLC_MAX_MTU, GFP_KERNEL);
3732 if (!card->tty_rx){
3733 /* Free the buffer above */
3734 kfree(card->tty_buf);
3735 card->tty_buf=NULL;
3736 card->tty=NULL;
3737 return -ENOMEM;
3742 ++card->tty_open;
3743 wanpipe_open(card);
3744 return 0;
3747 static int wanpipe_tty_write(struct tty_struct * tty, int from_user,
3748 const unsigned char *buf, int count)
3750 unsigned long smp_flags=0;
3751 sdla_t *card=NULL;
3753 if (!tty){
3754 dbg_printk(KERN_INFO "NO TTY in Write\n");
3755 return -ENODEV;
3758 card = (sdla_t *)tty->driver_data;
3760 if (!card){
3761 dbg_printk(KERN_INFO "No Card in TTY Write\n");
3762 return -ENODEV;
3765 if (count > card->wandev.mtu){
3766 dbg_printk(KERN_INFO "Frame too big in Write %i Max: %i\n",
3767 count,card->wandev.mtu);
3768 return -EINVAL;
3771 if (card->wandev.state != WAN_CONNECTED){
3772 dbg_printk(KERN_INFO "Card not connected in TTY Write\n");
3773 return -EINVAL;
3776 /* Lock the 508 Card: SMP is supported */
3777 if(card->hw.type != SDLA_S514){
3778 s508_lock(card,&smp_flags);
3781 if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){
3782 printk(KERN_INFO "%s: Critical in TTY Write\n",
3783 card->devname);
3785 /* Lock the 508 Card: SMP is supported */
3786 if(card->hw.type != SDLA_S514)
3787 s508_unlock(card,&smp_flags);
3789 return -EINVAL;
3792 if (from_user) {
3794 unsigned char *tmp_buf;
3796 if ((tmp_buf=card->tty_buf)==NULL){
3797 dbg_printk(KERN_INFO "No TTY BUF in Write\n");
3799 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
3801 if(card->hw.type != SDLA_S514)
3802 s508_unlock(card,&smp_flags);
3804 return -ENOMEM;
3807 if (copy_from_user(tmp_buf,buf,count)){
3808 dbg_printk(KERN_INFO "%s: Failed to copy from user!\n",
3809 card->devname);
3811 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
3813 if(card->hw.type != SDLA_S514)
3814 s508_unlock(card,&smp_flags);
3816 return -EINVAL;
3819 if (chdlc_send(card,(void*)tmp_buf,count)){
3820 dbg_printk(KERN_INFO "%s: Failed to send, retry later: user!\n",
3821 card->devname);
3823 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
3825 wanpipe_tty_trigger_tx_irq(card);
3827 if(card->hw.type != SDLA_S514)
3828 s508_unlock(card,&smp_flags);
3829 return 0;
3832 }else{
3833 if (chdlc_send(card,(void*)buf,count)){
3834 dbg_printk(KERN_INFO "%s: Failed to send, retry later: kernel!\n",
3835 card->devname);
3836 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
3838 wanpipe_tty_trigger_tx_irq(card);
3840 if(card->hw.type != SDLA_S514)
3841 s508_unlock(card,&smp_flags);
3842 return 0;
3845 dbg_printk(KERN_INFO "%s: Packet sent OK: %i\n",card->devname,count);
3846 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
3848 if(card->hw.type != SDLA_S514)
3849 s508_unlock(card,&smp_flags);
3851 return count;
3854 static void wanpipe_tty_receive(sdla_t *card, unsigned addr, unsigned int len)
3856 unsigned offset=0;
3857 unsigned olen=len;
3858 char fp=0;
3859 struct tty_struct *tty;
3860 int i;
3862 if (!card->tty_open){
3863 dbg_printk(KERN_INFO "%s: TTY not open during receive\n",
3864 card->devname);
3865 return;
3868 if ((tty=card->tty) == NULL){
3869 dbg_printk(KERN_INFO "%s: No TTY on receive\n",
3870 card->devname);
3871 return;
3874 if (!tty->driver_data){
3875 dbg_printk(KERN_INFO "%s: No Driver Data, or Flip on receive\n",
3876 card->devname);
3877 return;
3881 if (card->u.c.async_mode){
3882 if ((tty->flip.count+len) >= TTY_FLIPBUF_SIZE){
3883 if (net_ratelimit()){
3884 printk(KERN_INFO
3885 "%s: Received packet size too big: %i bytes, Max: %i!\n",
3886 card->devname,len,TTY_FLIPBUF_SIZE);
3888 return;
3892 if((addr + len) > card->u.c.rx_top + 1) {
3893 offset = card->u.c.rx_top - addr + 1;
3895 sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, offset);
3897 addr = card->u.c.rx_base;
3898 len -= offset;
3900 tty->flip.char_buf_ptr+=offset;
3901 tty->flip.count+=offset;
3902 for (i=0;i<offset;i++){
3903 *tty->flip.flag_buf_ptr = 0;
3904 tty->flip.flag_buf_ptr++;
3908 sdla_peek(&card->hw, addr, tty->flip.char_buf_ptr, len);
3910 tty->flip.char_buf_ptr+=len;
3911 card->tty->flip.count+=len;
3912 for (i=0;i<len;i++){
3913 *tty->flip.flag_buf_ptr = 0;
3914 tty->flip.flag_buf_ptr++;
3917 tty->low_latency=1;
3918 tty_flip_buffer_push(tty);
3919 }else{
3920 if (!card->tty_rx){
3921 if (net_ratelimit()){
3922 printk(KERN_INFO
3923 "%s: Receive sync buffer not available!\n",
3924 card->devname);
3926 return;
3929 if (len > TTY_CHDLC_MAX_MTU){
3930 if (net_ratelimit()){
3931 printk(KERN_INFO
3932 "%s: Received packet size too big: %i bytes, Max: %i!\n",
3933 card->devname,len,TTY_FLIPBUF_SIZE);
3935 return;
3939 if((addr + len) > card->u.c.rx_top + 1) {
3940 offset = card->u.c.rx_top - addr + 1;
3942 sdla_peek(&card->hw, addr, card->tty_rx, offset);
3944 addr = card->u.c.rx_base;
3945 len -= offset;
3947 sdla_peek(&card->hw, addr, card->tty_rx+offset, len);
3948 if (tty->ldisc.receive_buf){
3949 tty->ldisc.receive_buf(tty,card->tty_rx,&fp,olen);
3950 }else{
3951 if (net_ratelimit()){
3952 printk(KERN_INFO
3953 "%s: NO TTY Sync line discipline!\n",
3954 card->devname);
3959 dbg_printk(KERN_INFO "%s: Received Data %i\n",card->devname,olen);
3960 return;
3963 #if 0
3964 static int wanpipe_tty_ioctl(struct tty_struct *tty, struct file * file,
3965 unsigned int cmd, unsigned long arg)
3967 return -ENOIOCTLCMD;
3969 #endif
3971 static void wanpipe_tty_stop(struct tty_struct *tty)
3973 return;
3976 static void wanpipe_tty_start(struct tty_struct *tty)
3978 return;
3981 static int config_tty (sdla_t *card)
3983 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
3985 /* Setup the Board for asynchronous mode */
3986 if (card->u.c.async_mode){
3988 if (set_asy_config(card)) {
3989 printk (KERN_INFO "%s: Failed CHDLC Async configuration!\n",
3990 card->devname);
3991 return -EINVAL;
3993 }else{
3994 /* Setup the Board for CHDLC */
3995 if (set_chdlc_config(card)) {
3996 printk (KERN_INFO "%s: Failed CHDLC configuration!\n",
3997 card->devname);
3998 return -EINVAL;
4002 /* Set interrupt mode and mask */
4003 if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
4004 APP_INT_ON_GLOBAL_EXCEP_COND |
4005 APP_INT_ON_TX_FRAME |
4006 APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
4007 printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
4008 card->devname);
4009 return -EINVAL;
4013 /* Mask the Transmit and Timer interrupt */
4014 flags->interrupt_info_struct.interrupt_permission &=
4015 ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
4018 /* Enable communications */
4019 if (card->u.c.async_mode){
4020 if (asy_comm_enable(card) != 0) {
4021 printk(KERN_INFO "%s: Failed to enable async commnunication!\n",
4022 card->devname);
4023 flags->interrupt_info_struct.interrupt_permission = 0;
4024 card->u.c.comm_enabled=0;
4025 chdlc_set_intr_mode(card,0);
4026 return -EINVAL;
4028 }else{
4029 if (chdlc_comm_enable(card) != 0) {
4030 printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
4031 card->devname);
4032 flags->interrupt_info_struct.interrupt_permission = 0;
4033 card->u.c.comm_enabled=0;
4034 chdlc_set_intr_mode(card,0);
4035 return -EINVAL;
4039 /* Initialize Rx/Tx buffer control fields */
4040 init_chdlc_tx_rx_buff(card);
4041 port_set_state(card, WAN_CONNECTING);
4042 return 0;
4046 static int change_speed(sdla_t *card, struct tty_struct *tty,
4047 struct termios *old_termios)
4049 int baud, ret=0;
4050 unsigned cflag;
4051 int dbits,sbits,parity,handshaking;
4053 cflag = tty->termios->c_cflag;
4055 /* There is always one stop bit */
4056 sbits=WANOPT_ONE;
4058 /* Parity is defaulted to NONE */
4059 parity = WANOPT_NONE;
4061 handshaking=0;
4063 /* byte size and parity */
4064 switch (cflag & CSIZE) {
4065 case CS5: dbits = 5; break;
4066 case CS6: dbits = 6; break;
4067 case CS7: dbits = 7; break;
4068 case CS8: dbits = 8; break;
4069 /* Never happens, but GCC is too dumb to figure it out */
4070 default: dbits = 8; break;
4073 /* One more stop bit should be supported, thus increment
4074 * the number of stop bits Max=2 */
4075 if (cflag & CSTOPB) {
4076 sbits = WANOPT_TWO;
4078 if (cflag & PARENB) {
4079 parity = WANOPT_EVEN;
4081 if (cflag & PARODD){
4082 parity = WANOPT_ODD;
4085 /* Determine divisor based on baud rate */
4086 baud = tty_get_baud_rate(tty);
4088 if (!baud)
4089 baud = 9600; /* B0 transition handled in rs_set_termios */
4091 if (cflag & CRTSCTS) {
4092 handshaking|=ASY_RTS_HS_FOR_RX;
4095 if (I_IGNPAR(tty))
4096 parity = WANOPT_NONE;
4098 if (I_IXOFF(tty)){
4099 handshaking|=ASY_XON_XOFF_HS_FOR_RX;
4100 handshaking|=ASY_XON_XOFF_HS_FOR_TX;
4103 if (I_IXON(tty)){
4104 handshaking|=ASY_XON_XOFF_HS_FOR_RX;
4105 handshaking|=ASY_XON_XOFF_HS_FOR_TX;
4108 if (card->u.c.async_mode){
4109 if (card->wandev.bps != baud)
4110 ret=1;
4111 card->wandev.bps = baud;
4114 if (card->u.c.async_mode){
4115 if (card->u.c.protocol_options != handshaking)
4116 ret=1;
4117 card->u.c.protocol_options = handshaking;
4119 if (card->u.c.tx_bits_per_char != dbits)
4120 ret=1;
4121 card->u.c.tx_bits_per_char = dbits;
4123 if (card->u.c.rx_bits_per_char != dbits)
4124 ret=1;
4125 card->u.c.rx_bits_per_char = dbits;
4127 if (card->u.c.stop_bits != sbits)
4128 ret=1;
4129 card->u.c.stop_bits = sbits;
4131 if (card->u.c.parity != parity)
4132 ret=1;
4133 card->u.c.parity = parity;
4135 card->u.c.break_timer = 50;
4136 card->u.c.inter_char_timer = 10;
4137 card->u.c.rx_complete_length = 100;
4138 card->u.c.xon_char = 0xFE;
4139 }else{
4140 card->u.c.protocol_options = HDLC_STREAMING_MODE;
4143 return ret;
4147 static void wanpipe_tty_set_termios(struct tty_struct *tty, struct termios *old_termios)
4149 sdla_t *card;
4150 int err=1;
4152 if (!tty){
4153 return;
4156 card = (sdla_t *)tty->driver_data;
4158 if (!card)
4159 return;
4161 if (change_speed(card, tty, old_termios) || !card->u.c.comm_enabled){
4162 unsigned long smp_flags;
4164 if (card->u.c.comm_enabled){
4165 lock_adapter_irq(&card->wandev.lock,&smp_flags);
4166 chdlc_disable_comm_shutdown(card);
4167 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
4169 lock_adapter_irq(&card->wandev.lock,&smp_flags);
4170 err = config_tty(card);
4171 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
4172 if (card->u.c.async_mode){
4173 printk(KERN_INFO "%s: TTY Async Configuration:\n"
4174 " Baud =%i\n"
4175 " Handshaking =%s\n"
4176 " Tx Dbits =%i\n"
4177 " Rx Dbits =%i\n"
4178 " Parity =%s\n"
4179 " Stop Bits =%i\n",
4180 card->devname,
4181 card->wandev.bps,
4182 opt_decode[card->u.c.protocol_options],
4183 card->u.c.tx_bits_per_char,
4184 card->u.c.rx_bits_per_char,
4185 p_decode[card->u.c.parity] ,
4186 card->u.c.stop_bits);
4187 }else{
4188 printk(KERN_INFO "%s: TTY Sync Configuration:\n"
4189 " Baud =%i\n"
4190 " Protocol =HDLC_STREAMING\n",
4191 card->devname,card->wandev.bps);
4193 if (!err){
4194 port_set_state(card,WAN_CONNECTED);
4195 }else{
4196 port_set_state(card,WAN_DISCONNECTED);
4199 return;
4202 static void wanpipe_tty_put_char(struct tty_struct *tty, unsigned char ch)
4204 sdla_t *card;
4205 unsigned long smp_flags=0;
4207 if (!tty){
4208 return;
4211 card = (sdla_t *)tty->driver_data;
4213 if (!card)
4214 return;
4216 if (card->wandev.state != WAN_CONNECTED)
4217 return;
4219 if(card->hw.type != SDLA_S514)
4220 s508_lock(card,&smp_flags);
4222 if (test_and_set_bit(SEND_CRIT,(void*)&card->wandev.critical)){
4224 wanpipe_tty_trigger_tx_irq(card);
4226 if(card->hw.type != SDLA_S514)
4227 s508_unlock(card,&smp_flags);
4228 return;
4231 if (chdlc_send(card,(void*)&ch,1)){
4232 wanpipe_tty_trigger_tx_irq(card);
4233 dbg_printk("%s: Failed to TX char!\n",card->devname);
4236 dbg_printk("%s: Char TX OK\n",card->devname);
4238 clear_bit(SEND_CRIT,(void*)&card->wandev.critical);
4240 if(card->hw.type != SDLA_S514)
4241 s508_unlock(card,&smp_flags);
4243 return;
4246 static void wanpipe_tty_flush_chars(struct tty_struct *tty)
4248 return;
4251 static void wanpipe_tty_flush_buffer(struct tty_struct *tty)
4253 if (!tty)
4254 return;
4256 wake_up_interruptible(&tty->write_wait);
4257 #if defined(SERIAL_HAVE_POLL_WAIT)
4258 wake_up_interruptible(&tty->poll_wait);
4259 #endif
4260 if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
4261 tty->ldisc.write_wakeup)
4262 (tty->ldisc.write_wakeup)(tty);
4264 return;
4268 * This function is used to send a high-priority XON/XOFF character to
4269 * the device
4271 static void wanpipe_tty_send_xchar(struct tty_struct *tty, char ch)
4273 return;
4277 static int wanpipe_tty_chars_in_buffer(struct tty_struct *tty)
4279 return 0;
4283 static int wanpipe_tty_write_room(struct tty_struct *tty)
4285 sdla_t *card;
4287 printk(KERN_INFO "TTY Write Room\n");
4289 if (!tty){
4290 return 0;
4293 card = (sdla_t *)tty->driver_data;
4294 if (!card)
4295 return 0;
4297 if (card->wandev.state != WAN_CONNECTED)
4298 return 0;
4300 return SEC_MAX_NO_DATA_BYTES_IN_FRAME;
4304 static int set_modem_status(sdla_t *card, unsigned char data)
4306 CHDLC_MAILBOX_STRUCT *mb = card->mbox;
4307 int err;
4309 mb->buffer_length=1;
4310 mb->command=SET_MODEM_STATUS;
4311 mb->data[0]=data;
4312 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
4313 if (err != COMMAND_OK)
4314 chdlc_error (card, err, mb);
4316 return err;
4319 static void wanpipe_tty_hangup(struct tty_struct *tty)
4321 sdla_t *card;
4322 unsigned long smp_flags;
4324 printk(KERN_INFO "TTY Hangup!\n");
4326 if (!tty){
4327 return;
4330 card = (sdla_t *)tty->driver_data;
4331 if (!card)
4332 return;
4334 lock_adapter_irq(&card->wandev.lock,&smp_flags);
4335 set_modem_status(card,0);
4336 unlock_adapter_irq(&card->wandev.lock,&smp_flags);
4337 return;
4340 static void wanpipe_tty_break(struct tty_struct *tty, int break_state)
4342 return;
4345 static void wanpipe_tty_wait_until_sent(struct tty_struct *tty, int timeout)
4347 return;
4350 static void wanpipe_tty_throttle(struct tty_struct * tty)
4352 return;
4355 static void wanpipe_tty_unthrottle(struct tty_struct * tty)
4357 return;
4360 int wanpipe_tty_read_proc(char *page, char **start, off_t off, int count,
4361 int *eof, void *data)
4363 return 0;
4367 * The serial driver boot-time initialization code!
4369 int wanpipe_tty_init(sdla_t *card)
4371 struct serial_state * state;
4373 /* Initialize the tty_driver structure */
4375 if (card->tty_minor < 0 || card->tty_minor > NR_PORTS){
4376 printk(KERN_INFO "%s: Illegal Minor TTY number (0-4): %i\n",
4377 card->devname,card->tty_minor);
4378 return -EINVAL;
4381 if (WAN_CARD(card->tty_minor)){
4382 printk(KERN_INFO "%s: TTY Minor %i, already in use\n",
4383 card->devname,card->tty_minor);
4384 return -EBUSY;
4387 if (tty_init_cnt==0){
4389 printk(KERN_INFO "%s: TTY %s Driver Init: Major %i, Minor Range %i-%i\n",
4390 card->devname,
4391 card->u.c.async_mode ? "ASYNC" : "SYNC",
4392 WAN_TTY_MAJOR,MIN_PORT,MAX_PORT);
4394 tty_driver_mode = card->u.c.async_mode;
4396 memset(&serial_driver, 0, sizeof(struct tty_driver));
4397 serial_driver.magic = TTY_DRIVER_MAGIC;
4398 serial_driver.owner = THIS_MODULE;
4399 serial_driver.driver_name = "wanpipe_tty";
4400 serial_driver.name = "ttyW";
4401 serial_driver.major = WAN_TTY_MAJOR;
4402 serial_driver.minor_start = WAN_TTY_MINOR;
4403 serial_driver.num = NR_PORTS;
4404 serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
4405 serial_driver.subtype = SERIAL_TYPE_NORMAL;
4407 serial_driver.init_termios = tty_std_termios;
4408 serial_driver.init_termios.c_cflag =
4409 B9600 | CS8 | CREAD | HUPCL | CLOCAL;
4410 serial_driver.flags = TTY_DRIVER_REAL_RAW;
4412 serial_driver.refcount = 1; /* !@!@^#^&!! */
4414 serial_driver.open = wanpipe_tty_open;
4415 serial_driver.close = wanpipe_tty_close;
4416 serial_driver.write = wanpipe_tty_write;
4418 serial_driver.put_char = wanpipe_tty_put_char;
4419 serial_driver.flush_chars = wanpipe_tty_flush_chars;
4420 serial_driver.write_room = wanpipe_tty_write_room;
4421 serial_driver.chars_in_buffer = wanpipe_tty_chars_in_buffer;
4422 serial_driver.flush_buffer = wanpipe_tty_flush_buffer;
4423 //serial_driver.ioctl = wanpipe_tty_ioctl;
4424 serial_driver.throttle = wanpipe_tty_throttle;
4425 serial_driver.unthrottle = wanpipe_tty_unthrottle;
4426 serial_driver.send_xchar = wanpipe_tty_send_xchar;
4427 serial_driver.set_termios = wanpipe_tty_set_termios;
4428 serial_driver.stop = wanpipe_tty_stop;
4429 serial_driver.start = wanpipe_tty_start;
4430 serial_driver.hangup = wanpipe_tty_hangup;
4431 serial_driver.break_ctl = wanpipe_tty_break;
4432 serial_driver.wait_until_sent = wanpipe_tty_wait_until_sent;
4433 serial_driver.read_proc = wanpipe_tty_read_proc;
4435 if (tty_register_driver(&serial_driver)){
4436 printk(KERN_INFO "%s: Failed to register serial driver!\n",
4437 card->devname);
4442 /* The subsequent ports must comply to the initial configuration */
4443 if (tty_driver_mode != card->u.c.async_mode){
4444 printk(KERN_INFO "%s: Error: TTY Driver operation mode mismatch!\n",
4445 card->devname);
4446 printk(KERN_INFO "%s: The TTY driver is configured for %s!\n",
4447 card->devname, tty_driver_mode ? "ASYNC" : "SYNC");
4448 return -EINVAL;
4451 tty_init_cnt++;
4453 printk(KERN_INFO "%s: Initializing TTY %s Driver Minor %i\n",
4454 card->devname,
4455 tty_driver_mode ? "ASYNC" : "SYNC",
4456 card->tty_minor);
4458 tty_card_map[card->tty_minor] = card;
4459 state = &rs_table[card->tty_minor];
4461 state->magic = SSTATE_MAGIC;
4462 state->line = 0;
4463 state->type = PORT_UNKNOWN;
4464 state->custom_divisor = 0;
4465 state->close_delay = 5*HZ/10;
4466 state->closing_wait = 30*HZ;
4467 state->icount.cts = state->icount.dsr =
4468 state->icount.rng = state->icount.dcd = 0;
4469 state->icount.rx = state->icount.tx = 0;
4470 state->icount.frame = state->icount.parity = 0;
4471 state->icount.overrun = state->icount.brk = 0;
4472 state->irq = card->wandev.irq;
4474 INIT_WORK(&card->tty_work, tty_poll_work, (void*)card);
4475 return 0;
4479 MODULE_LICENSE("GPL");
4481 /****** End ****************************************************************/