[XFS] add handlers to fix xfs_flock_t alignment issues in compat ioctls
[linux-2.6/mini2440.git] / drivers / net / wan / wanpipe_multppp.c
blob812a1183c502bfa7de160e3a55ebee74b0301d5a
1 /*****************************************************************************
2 * wanpipe_multppp.c Multi-Port PPP driver module.
4 * Authors: Nenad Corbic <ncorbic@sangoma.com>
6 * Copyright: (c) 1995-2001 Sangoma Technologies Inc.
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 * ============================================================================
13 * Dec 15 2000 Updated for 2.4.X kernel
14 * Nov 15 2000 Fixed the SyncPPP support for kernels 2.2.16 and higher.
15 * The pppstruct has changed.
16 * Jul 13 2000 Using the kernel Syncppp module on top of RAW Wanpipe CHDLC
17 * module.
18 *****************************************************************************/
20 #include <linux/module.h>
21 #include <linux/kernel.h> /* printk(), and other useful stuff */
22 #include <linux/stddef.h> /* offsetof(), etc. */
23 #include <linux/errno.h> /* return codes */
24 #include <linux/string.h> /* inline memset(), etc. */
25 #include <linux/slab.h> /* kmalloc(), kfree() */
26 #include <linux/wanrouter.h> /* WAN router definitions */
27 #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
28 #include <linux/if_arp.h> /* ARPHRD_* defines */
29 #include <linux/jiffies.h> /* time_after() macro */
31 #include <linux/in.h> /* sockaddr_in */
32 #include <linux/inet.h>
33 #include <linux/if.h>
34 #include <asm/byteorder.h> /* htons(), etc. */
35 #include <linux/sdlapci.h>
36 #include <asm/io.h>
38 #include <linux/sdla_chdlc.h> /* CHDLC firmware API definitions */
39 #include <linux/sdla_asy.h> /* CHDLC (async) API definitions */
41 #include <linux/if_wanpipe_common.h> /* Socket Driver common area */
42 #include <linux/if_wanpipe.h>
45 #include <linux/inetdevice.h>
46 #include <asm/uaccess.h>
48 #include <net/syncppp.h>
51 /****** Defines & Macros ****************************************************/
53 #ifdef _DEBUG_
54 #define STATIC
55 #else
56 #define STATIC static
57 #endif
59 /* reasons for enabling the timer interrupt on the adapter */
60 #define TMR_INT_ENABLED_UDP 0x01
61 #define TMR_INT_ENABLED_UPDATE 0x02
62 #define TMR_INT_ENABLED_CONFIG 0x04
64 #define CHDLC_DFLT_DATA_LEN 1500 /* default MTU */
65 #define CHDLC_HDR_LEN 1
67 #define IFF_POINTTOPOINT 0x10
69 #define CHDLC_API 0x01
71 #define PORT(x) (x == 0 ? "PRIMARY" : "SECONDARY" )
72 #define MAX_BH_BUFF 10
74 #define CRC_LENGTH 2
75 #define PPP_HEADER_LEN 4
77 /******Data Structures*****************************************************/
79 /* This structure is placed in the private data area of the device structure.
80 * The card structure used to occupy the private area but now the following
81 * structure will incorporate the card structure along with CHDLC specific data
84 typedef struct chdlc_private_area
86 void *if_ptr; /* General Pointer used by SPPP */
87 wanpipe_common_t common;
88 sdla_t *card;
89 int TracingEnabled; /* For enabling Tracing */
90 unsigned long curr_trace_addr; /* Used for Tracing */
91 unsigned long start_trace_addr;
92 unsigned long end_trace_addr;
93 unsigned long base_addr_trace_buffer;
94 unsigned long end_addr_trace_buffer;
95 unsigned short number_trace_elements;
96 unsigned available_buffer_space;
97 unsigned long router_start_time;
98 unsigned char route_status;
99 unsigned char route_removed;
100 unsigned long tick_counter; /* For 5s timeout counter */
101 unsigned long router_up_time;
102 u32 IP_address; /* IP addressing */
103 u32 IP_netmask;
104 unsigned char mc; /* Mulitcast support on/off */
105 unsigned short udp_pkt_lgth; /* udp packet processing */
106 char udp_pkt_src;
107 char udp_pkt_data[MAX_LGTH_UDP_MGNT_PKT];
108 unsigned short timer_int_enabled;
109 char update_comms_stats; /* updating comms stats */
111 //FIXME: add driver stats as per frame relay!
113 } chdlc_private_area_t;
115 /* Route Status options */
116 #define NO_ROUTE 0x00
117 #define ADD_ROUTE 0x01
118 #define ROUTE_ADDED 0x02
119 #define REMOVE_ROUTE 0x03
122 /* variable for keeping track of enabling/disabling FT1 monitor status */
123 static int rCount = 0;
125 /* variable for tracking how many interfaces to open for WANPIPE on the
126 two ports */
128 extern void disable_irq(unsigned int);
129 extern void enable_irq(unsigned int);
131 /****** Function Prototypes *************************************************/
132 /* WAN link driver entry points. These are called by the WAN router module. */
133 static int update(struct wan_device* wandev);
134 static int new_if(struct wan_device* wandev, struct net_device* dev,
135 wanif_conf_t* conf);
136 static int del_if(struct wan_device* wandev, struct net_device* dev);
138 /* Network device interface */
139 static int if_init(struct net_device* dev);
140 static int if_open(struct net_device* dev);
141 static int if_close(struct net_device* dev);
142 static int if_send(struct sk_buff* skb, struct net_device* dev);
143 static struct net_device_stats* if_stats(struct net_device* dev);
145 static void if_tx_timeout(struct net_device *dev);
147 /* CHDLC Firmware interface functions */
148 static int chdlc_configure (sdla_t* card, void* data);
149 static int chdlc_comm_enable (sdla_t* card);
150 static int chdlc_comm_disable (sdla_t* card);
151 static int chdlc_read_version (sdla_t* card, char* str);
152 static int chdlc_set_intr_mode (sdla_t* card, unsigned mode);
153 static int chdlc_send (sdla_t* card, void* data, unsigned len);
154 static int chdlc_read_comm_err_stats (sdla_t* card);
155 static int chdlc_read_op_stats (sdla_t* card);
156 static int config_chdlc (sdla_t *card);
159 /* Miscellaneous CHDLC Functions */
160 static int set_chdlc_config (sdla_t* card);
161 static void init_chdlc_tx_rx_buff(sdla_t* card, struct net_device *dev);
162 static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb);
163 static int process_chdlc_exception(sdla_t *card);
164 static int process_global_exception(sdla_t *card);
165 static int update_comms_stats(sdla_t* card,
166 chdlc_private_area_t* chdlc_priv_area);
167 static void port_set_state (sdla_t *card, int);
169 /* Interrupt handlers */
170 static void wsppp_isr (sdla_t* card);
171 static void rx_intr (sdla_t* card);
172 static void timer_intr(sdla_t *);
174 /* Miscellaneous functions */
175 static int reply_udp( unsigned char *data, unsigned int mbox_len );
176 static int intr_test( sdla_t* card);
177 static int udp_pkt_type( struct sk_buff *skb , sdla_t* card);
178 static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
179 struct sk_buff *skb, struct net_device* dev,
180 chdlc_private_area_t* chdlc_priv_area);
181 static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
182 chdlc_private_area_t* chdlc_priv_area);
183 static unsigned short calc_checksum (char *, int);
184 static void s508_lock (sdla_t *card, unsigned long *smp_flags);
185 static void s508_unlock (sdla_t *card, unsigned long *smp_flags);
186 static void send_ppp_term_request(struct net_device *dev);
189 static int Intr_test_counter;
190 /****** Public Functions ****************************************************/
192 /*============================================================================
193 * Cisco HDLC protocol initialization routine.
195 * This routine is called by the main WANPIPE module during setup. At this
196 * point adapter is completely initialized and firmware is running.
197 * o read firmware version (to make sure it's alive)
198 * o configure adapter
199 * o initialize protocol-specific fields of the adapter data space.
201 * Return: 0 o.k.
202 * < 0 failure.
204 int wsppp_init (sdla_t* card, wandev_conf_t* conf)
206 unsigned char port_num;
207 int err;
208 unsigned long max_permitted_baud = 0;
209 SHARED_MEMORY_INFO_STRUCT *flags;
211 union
213 char str[80];
214 } u;
215 volatile CHDLC_MAILBOX_STRUCT* mb;
216 CHDLC_MAILBOX_STRUCT* mb1;
217 unsigned long timeout;
219 /* Verify configuration ID */
220 if (conf->config_id != WANCONFIG_MPPP) {
221 printk(KERN_INFO "%s: invalid configuration ID %u!\n",
222 card->devname, conf->config_id);
223 return -EINVAL;
226 /* Find out which Port to use */
227 if ((conf->comm_port == WANOPT_PRI) || (conf->comm_port == WANOPT_SEC)){
228 if (card->next){
230 if (conf->comm_port != card->next->u.c.comm_port){
231 card->u.c.comm_port = conf->comm_port;
232 }else{
233 printk(KERN_ERR "%s: ERROR - %s port used!\n",
234 card->wandev.name, PORT(conf->comm_port));
235 return -EINVAL;
237 }else{
238 card->u.c.comm_port = conf->comm_port;
240 }else{
241 printk(KERN_ERR "%s: ERROR - Invalid Port Selected!\n",
242 card->wandev.name);
243 return -EINVAL;
247 /* Initialize protocol-specific fields */
248 if(card->hw.type != SDLA_S514){
250 if (card->u.c.comm_port == WANOPT_PRI){
251 card->mbox = (void *) card->hw.dpmbase;
252 }else{
253 card->mbox = (void *) card->hw.dpmbase +
254 SEC_BASE_ADDR_MB_STRUCT - PRI_BASE_ADDR_MB_STRUCT;
256 }else{
257 /* for a S514 adapter, set a pointer to the actual mailbox in the */
258 /* allocated virtual memory area */
259 if (card->u.c.comm_port == WANOPT_PRI){
260 card->mbox = (void *) card->hw.dpmbase + PRI_BASE_ADDR_MB_STRUCT;
261 }else{
262 card->mbox = (void *) card->hw.dpmbase + SEC_BASE_ADDR_MB_STRUCT;
266 mb = mb1 = card->mbox;
268 if (!card->configured){
270 /* The board will place an 'I' in the return code to indicate that it is
271 ready to accept commands. We expect this to be completed in less
272 than 1 second. */
274 timeout = jiffies + 1 * HZ;
275 while (mb->return_code != 'I') /* Wait 1s for board to initialize */
276 if (time_after(jiffies, timeout)) break;
278 if (mb->return_code != 'I') {
279 printk(KERN_INFO
280 "%s: Initialization not completed by adapter\n",
281 card->devname);
282 printk(KERN_INFO "Please contact Sangoma representative.\n");
283 return -EIO;
287 /* Read firmware version. Note that when adapter initializes, it
288 * clears the mailbox, so it may appear that the first command was
289 * executed successfully when in fact it was merely erased. To work
290 * around this, we execute the first command twice.
293 if (chdlc_read_version(card, u.str))
294 return -EIO;
296 printk(KERN_INFO "%s: Running Raw CHDLC firmware v%s\n"
297 "%s: for Multi-Port PPP protocol.\n",
298 card->devname,u.str,card->devname);
300 card->isr = &wsppp_isr;
301 card->poll = NULL;
302 card->exec = NULL;
303 card->wandev.update = &update;
304 card->wandev.new_if = &new_if;
305 card->wandev.del_if = &del_if;
306 card->wandev.udp_port = conf->udp_port;
308 card->wandev.new_if_cnt = 0;
310 /* reset the number of times the 'update()' proc has been called */
311 card->u.c.update_call_count = 0;
313 card->wandev.ttl = conf->ttl;
314 card->wandev.interface = conf->interface;
316 if ((card->u.c.comm_port == WANOPT_SEC && conf->interface == WANOPT_V35)&&
317 card->hw.type != SDLA_S514){
318 printk(KERN_INFO "%s: ERROR - V35 Interface not supported on S508 %s port \n",
319 card->devname, PORT(card->u.c.comm_port));
320 return -EIO;
324 card->wandev.clocking = conf->clocking;
326 port_num = card->u.c.comm_port;
328 /* Setup Port Bps */
330 if(card->wandev.clocking) {
331 if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
332 /* For Primary Port 0 */
333 max_permitted_baud =
334 (card->hw.type == SDLA_S514) ?
335 PRI_MAX_BAUD_RATE_S514 :
336 PRI_MAX_BAUD_RATE_S508;
338 else if(port_num == WANOPT_SEC) {
339 /* For Secondary Port 1 */
340 max_permitted_baud =
341 (card->hw.type == SDLA_S514) ?
342 SEC_MAX_BAUD_RATE_S514 :
343 SEC_MAX_BAUD_RATE_S508;
346 if(conf->bps > max_permitted_baud) {
347 conf->bps = max_permitted_baud;
348 printk(KERN_INFO "%s: Baud too high!\n",
349 card->wandev.name);
350 printk(KERN_INFO "%s: Baud rate set to %lu bps\n",
351 card->wandev.name, max_permitted_baud);
354 card->wandev.bps = conf->bps;
355 }else{
356 card->wandev.bps = 0;
359 /* Setup the Port MTU */
360 if((port_num == WANOPT_PRI) || card->u.c.receive_only) {
362 /* For Primary Port 0 */
363 card->wandev.mtu =
364 (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
365 min_t(unsigned int, conf->mtu, PRI_MAX_NO_DATA_BYTES_IN_FRAME) :
366 CHDLC_DFLT_DATA_LEN;
367 } else if(port_num == WANOPT_SEC) {
368 /* For Secondary Port 1 */
369 card->wandev.mtu =
370 (conf->mtu >= MIN_LGTH_CHDLC_DATA_CFG) ?
371 min_t(unsigned int, conf->mtu, SEC_MAX_NO_DATA_BYTES_IN_FRAME) :
372 CHDLC_DFLT_DATA_LEN;
375 /* Add on a PPP Header */
376 card->wandev.mtu += PPP_HEADER_LEN;
378 /* Set up the interrupt status area */
379 /* Read the CHDLC Configuration and obtain:
380 * Ptr to shared memory infor struct
381 * Use this pointer to calculate the value of card->u.c.flags !
383 mb1->buffer_length = 0;
384 mb1->command = READ_CHDLC_CONFIGURATION;
385 err = sdla_exec(mb1) ? mb1->return_code : CMD_TIMEOUT;
386 if(err != COMMAND_OK) {
387 clear_bit(1, (void*)&card->wandev.critical);
389 if(card->hw.type != SDLA_S514)
390 enable_irq(card->hw.irq);
392 chdlc_error(card, err, mb1);
393 return -EIO;
396 if(card->hw.type == SDLA_S514){
397 card->u.c.flags = (void *)(card->hw.dpmbase +
398 (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
399 ptr_shared_mem_info_struct));
400 }else{
401 card->u.c.flags = (void *)(card->hw.dpmbase +
402 (((CHDLC_CONFIGURATION_STRUCT *)mb1->data)->
403 ptr_shared_mem_info_struct % SDLA_WINDOWSIZE));
406 flags = card->u.c.flags;
408 /* This is for the ports link state */
409 card->wandev.state = WAN_DUALPORT;
410 card->u.c.state = WAN_DISCONNECTED;
413 if (!card->wandev.piggyback){
414 err = intr_test(card);
416 if(err || (Intr_test_counter < MAX_INTR_TEST_COUNTER)) {
417 printk(KERN_ERR "%s: Interrupt test failed (%i)\n",
418 card->devname, Intr_test_counter);
419 printk(KERN_ERR "%s: Please choose another interrupt\n",
420 card->devname);
421 return -EIO;
424 printk(KERN_INFO "%s: Interrupt test passed (%i)\n",
425 card->devname, Intr_test_counter);
429 if (chdlc_set_intr_mode(card, APP_INT_ON_TIMER)){
430 printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
431 card->devname);
432 return -EIO;
435 /* Mask the Timer interrupt */
436 flags->interrupt_info_struct.interrupt_permission &=
437 ~APP_INT_ON_TIMER;
439 printk(KERN_INFO "\n");
441 return 0;
444 /******* WAN Device Driver Entry Points *************************************/
446 /*============================================================================
447 * Update device status & statistics
448 * This procedure is called when updating the PROC file system and returns
449 * various communications statistics. These statistics are accumulated from 3
450 * different locations:
451 * 1) The 'if_stats' recorded for the device.
452 * 2) Communication error statistics on the adapter.
453 * 3) CHDLC operational statistics on the adapter.
454 * The board level statistics are read during a timer interrupt. Note that we
455 * read the error and operational statistics during consecitive timer ticks so
456 * as to minimize the time that we are inside the interrupt handler.
459 static int update(struct wan_device* wandev)
461 sdla_t* card = wandev->private;
462 struct net_device* dev;
463 volatile chdlc_private_area_t* chdlc_priv_area;
464 SHARED_MEMORY_INFO_STRUCT *flags;
465 unsigned long timeout;
467 /* sanity checks */
468 if((wandev == NULL) || (wandev->private == NULL))
469 return -EFAULT;
471 if(wandev->state == WAN_UNCONFIGURED)
472 return -ENODEV;
474 /* more sanity checks */
475 if(!card->u.c.flags)
476 return -ENODEV;
478 if((dev=card->wandev.dev) == NULL)
479 return -ENODEV;
481 if((chdlc_priv_area=dev->priv) == NULL)
482 return -ENODEV;
484 flags = card->u.c.flags;
486 if(chdlc_priv_area->update_comms_stats){
487 return -EAGAIN;
490 /* we will need 2 timer interrupts to complete the */
491 /* reading of the statistics */
492 chdlc_priv_area->update_comms_stats = 2;
493 flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
494 chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UPDATE;
496 /* wait a maximum of 1 second for the statistics to be updated */
497 timeout = jiffies + 1 * HZ;
498 for(;;) {
499 if(chdlc_priv_area->update_comms_stats == 0)
500 break;
501 if (time_after(jiffies, timeout)){
502 chdlc_priv_area->update_comms_stats = 0;
503 chdlc_priv_area->timer_int_enabled &=
504 ~TMR_INT_ENABLED_UPDATE;
505 return -EAGAIN;
509 return 0;
513 /*============================================================================
514 * Create new logical channel.
515 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
516 * handled.
517 * o parse media- and hardware-specific configuration
518 * o make sure that a new channel can be created
519 * o allocate resources, if necessary
520 * o prepare network device structure for registaration.
522 * Return: 0 o.k.
523 * < 0 failure (channel will not be created)
525 static int new_if(struct wan_device* wandev, struct net_device* pdev,
526 wanif_conf_t* conf)
529 struct ppp_device *pppdev = (struct ppp_device *)pdev;
530 struct net_device *dev = NULL;
531 struct sppp *sp;
532 sdla_t* card = wandev->private;
533 chdlc_private_area_t* chdlc_priv_area;
535 if ((conf->name[0] == '\0') || (strlen(conf->name) > WAN_IFNAME_SZ)) {
536 printk(KERN_INFO "%s: invalid interface name!\n",
537 card->devname);
538 return -EINVAL;
541 /* allocate and initialize private data */
542 chdlc_priv_area = kmalloc(sizeof(chdlc_private_area_t), GFP_KERNEL);
544 if(chdlc_priv_area == NULL)
545 return -ENOMEM;
547 memset(chdlc_priv_area, 0, sizeof(chdlc_private_area_t));
549 chdlc_priv_area->card = card;
551 /* initialize data */
552 strcpy(card->u.c.if_name, conf->name);
554 if(card->wandev.new_if_cnt > 0) {
555 kfree(chdlc_priv_area);
556 return -EEXIST;
559 card->wandev.new_if_cnt++;
561 chdlc_priv_area->TracingEnabled = 0;
563 //We don't need this any more
564 chdlc_priv_area->route_status = NO_ROUTE;
565 chdlc_priv_area->route_removed = 0;
567 printk(KERN_INFO "%s: Firmware running in HDLC STREAMING Mode\n",
568 wandev->name);
570 /* Setup wanpipe as a router (WANPIPE) or as an API */
571 if( strcmp(conf->usedby, "WANPIPE") == 0) {
572 printk(KERN_INFO "%s: Driver running in WANPIPE mode!\n",
573 wandev->name);
574 card->u.c.usedby = WANPIPE;
575 } else {
576 printk(KERN_INFO
577 "%s: API Mode is not supported for SyncPPP!\n",
578 wandev->name);
579 kfree(chdlc_priv_area);
580 return -EINVAL;
583 /* Get Multicast Information */
584 chdlc_priv_area->mc = conf->mc;
587 chdlc_priv_area->if_ptr = pppdev;
589 /* prepare network device data space for registration */
591 strcpy(dev->name,card->u.c.if_name);
593 /* Attach PPP protocol layer to pppdev
594 * The sppp_attach() will initilize the dev structure
595 * and setup ppp layer protocols.
596 * All we have to do is to bind in:
597 * if_open(), if_close(), if_send() and get_stats() functions.
599 sppp_attach(pppdev);
600 dev = pppdev->dev;
601 sp = &pppdev->sppp;
603 /* Enable PPP Debugging */
604 // FIXME Fix this up somehow
605 //sp->pp_flags |= PP_DEBUG;
606 sp->pp_flags &= ~PP_CISCO;
608 dev->init = &if_init;
609 dev->priv = chdlc_priv_area;
611 return 0;
617 /*============================================================================
618 * Delete logical channel.
620 static int del_if(struct wan_device* wandev, struct net_device* dev)
622 chdlc_private_area_t *chdlc_priv_area = dev->priv;
623 sdla_t *card = chdlc_priv_area->card;
624 unsigned long smp_lock;
626 /* Detach the PPP layer */
627 printk(KERN_INFO "%s: Detaching SyncPPP Module from %s\n",
628 wandev->name,dev->name);
630 lock_adapter_irq(&wandev->lock,&smp_lock);
632 sppp_detach(dev);
633 chdlc_priv_area->if_ptr=NULL;
635 chdlc_set_intr_mode(card, 0);
636 if (card->u.c.comm_enabled)
637 chdlc_comm_disable(card);
638 unlock_adapter_irq(&wandev->lock,&smp_lock);
640 port_set_state(card, WAN_DISCONNECTED);
642 return 0;
646 /****** Network Device Interface ********************************************/
648 /*============================================================================
649 * Initialize Linux network interface.
651 * This routine is called only once for each interface, during Linux network
652 * interface registration. Returning anything but zero will fail interface
653 * registration.
655 static int if_init(struct net_device* dev)
657 chdlc_private_area_t* chdlc_priv_area = dev->priv;
658 sdla_t* card = chdlc_priv_area->card;
659 struct wan_device* wandev = &card->wandev;
661 /* NOTE: Most of the dev initialization was
662 * done in sppp_attach(), called by new_if()
663 * function. All we have to do here is
664 * to link four major routines below.
667 /* Initialize device driver entry points */
668 dev->open = &if_open;
669 dev->stop = &if_close;
670 dev->hard_start_xmit = &if_send;
671 dev->get_stats = &if_stats;
672 dev->tx_timeout = &if_tx_timeout;
673 dev->watchdog_timeo = TX_TIMEOUT;
676 /* Initialize hardware parameters */
677 dev->irq = wandev->irq;
678 dev->dma = wandev->dma;
679 dev->base_addr = wandev->ioport;
680 dev->mem_start = wandev->maddr;
681 dev->mem_end = wandev->maddr + wandev->msize - 1;
683 /* Set transmit buffer queue length
684 * If we over fill this queue the packets will
685 * be droped by the kernel.
686 * sppp_attach() sets this to 10, but
687 * 100 will give us more room at low speeds.
689 dev->tx_queue_len = 100;
691 return 0;
695 /*============================================================================
696 * Handle transmit timeout event from netif watchdog
698 static void if_tx_timeout(struct net_device *dev)
700 chdlc_private_area_t* chan = dev->priv;
701 sdla_t *card = chan->card;
703 /* If our device stays busy for at least 5 seconds then we will
704 * kick start the device by making dev->tbusy = 0. We expect
705 * that our device never stays busy more than 5 seconds. So this
706 * is only used as a last resort.
709 ++card->wandev.stats.collisions;
711 printk (KERN_INFO "%s: Transmit timed out on %s\n", card->devname,dev->name);
712 netif_wake_queue (dev);
716 /*============================================================================
717 * Open network interface.
718 * o enable communications and interrupts.
719 * o prevent module from unloading by incrementing use count
721 * Return 0 if O.k. or errno.
723 static int if_open(struct net_device* dev)
725 chdlc_private_area_t* chdlc_priv_area = dev->priv;
726 sdla_t* card = chdlc_priv_area->card;
727 struct timeval tv;
728 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
730 /* Only one open per interface is allowed */
731 if (netif_running(dev))
732 return -EBUSY;
734 /* Start PPP Layer */
735 if (sppp_open(dev)){
736 return -EIO;
739 do_gettimeofday(&tv);
740 chdlc_priv_area->router_start_time = tv.tv_sec;
742 netif_start_queue(dev);
744 wanpipe_open(card);
746 chdlc_priv_area->timer_int_enabled |= TMR_INT_ENABLED_CONFIG;
747 flags->interrupt_info_struct.interrupt_permission |= APP_INT_ON_TIMER;
748 return 0;
751 /*============================================================================
752 * Close network interface.
753 * o if this is the last close, then disable communications and interrupts.
754 * o reset flags.
756 static int if_close(struct net_device* dev)
758 chdlc_private_area_t* chdlc_priv_area = dev->priv;
759 sdla_t* card = chdlc_priv_area->card;
761 /* Stop the PPP Layer */
762 sppp_close(dev);
763 netif_stop_queue(dev);
765 wanpipe_close(card);
767 return 0;
770 /*============================================================================
771 * Send a packet on a network interface.
772 * o set tbusy flag (marks start of the transmission) to block a timer-based
773 * transmit from overlapping.
774 * o check link state. If link is not up, then drop the packet.
775 * o execute adapter send command.
776 * o free socket buffer
778 * Return: 0 complete (socket buffer must be freed)
779 * non-0 packet may be re-transmitted (tbusy must be set)
781 * Notes:
782 * 1. This routine is called either by the protocol stack or by the "net
783 * bottom half" (with interrupts enabled).
784 * 2. Setting tbusy flag will inhibit further transmit requests from the
785 * protocol stack and can be used for flow control with protocol layer.
787 static int if_send(struct sk_buff* skb, struct net_device* dev)
789 chdlc_private_area_t *chdlc_priv_area = dev->priv;
790 sdla_t *card = chdlc_priv_area->card;
791 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
792 INTERRUPT_INFORMATION_STRUCT *chdlc_int = &flags->interrupt_info_struct;
793 int udp_type = 0;
794 unsigned long smp_flags;
795 int err=0;
797 netif_stop_queue(dev);
800 if (skb == NULL){
801 /* If we get here, some higher layer thinks we've missed an
802 * tx-done interrupt.
804 printk(KERN_INFO "%s: Received NULL skb buffer! interface %s got kicked!\n",
805 card->devname, dev->name);
807 netif_wake_queue(dev);
808 return 0;
811 if (ntohs(skb->protocol) != htons(PVC_PROT)){
812 /* check the udp packet type */
814 udp_type = udp_pkt_type(skb, card);
815 if (udp_type == UDP_CPIPE_TYPE){
816 if(store_udp_mgmt_pkt(UDP_PKT_FRM_STACK, card, skb, dev,
817 chdlc_priv_area)){
818 chdlc_int->interrupt_permission |=
819 APP_INT_ON_TIMER;
821 netif_start_queue(dev);
822 return 0;
826 /* Lock the 508 Card: SMP is supported */
827 if(card->hw.type != SDLA_S514){
828 s508_lock(card,&smp_flags);
831 if (test_and_set_bit(SEND_CRIT, (void*)&card->wandev.critical)){
833 printk(KERN_INFO "%s: Critical in if_send: %lx\n",
834 card->wandev.name,card->wandev.critical);
835 ++card->wandev.stats.tx_dropped;
836 netif_start_queue(dev);
837 goto if_send_crit_exit;
840 if (card->wandev.state != WAN_CONNECTED){
841 ++card->wandev.stats.tx_dropped;
842 netif_start_queue(dev);
843 goto if_send_crit_exit;
846 if (chdlc_send(card, skb->data, skb->len)){
847 netif_stop_queue(dev);
849 }else{
850 ++card->wandev.stats.tx_packets;
851 card->wandev.stats.tx_bytes += skb->len;
852 dev->trans_start = jiffies;
853 netif_start_queue(dev);
856 if_send_crit_exit:
857 if (!(err=netif_queue_stopped(dev))){
858 dev_kfree_skb_any(skb);
859 }else{
860 chdlc_priv_area->tick_counter = jiffies;
861 chdlc_int->interrupt_permission |= APP_INT_ON_TX_FRAME;
864 clear_bit(SEND_CRIT, (void*)&card->wandev.critical);
865 if(card->hw.type != SDLA_S514){
866 s508_unlock(card,&smp_flags);
869 return err;
873 /*============================================================================
874 * Reply to UDP Management system.
875 * Return length of reply.
877 static int reply_udp( unsigned char *data, unsigned int mbox_len )
880 unsigned short len, udp_length, temp, ip_length;
881 unsigned long ip_temp;
882 int even_bound = 0;
883 chdlc_udp_pkt_t *c_udp_pkt = (chdlc_udp_pkt_t *)data;
885 /* Set length of packet */
886 len = sizeof(ip_pkt_t)+
887 sizeof(udp_pkt_t)+
888 sizeof(wp_mgmt_t)+
889 sizeof(cblock_t)+
890 sizeof(trace_info_t)+
891 mbox_len;
893 /* fill in UDP reply */
894 c_udp_pkt->wp_mgmt.request_reply = UDPMGMT_REPLY;
896 /* fill in UDP length */
897 udp_length = sizeof(udp_pkt_t)+
898 sizeof(wp_mgmt_t)+
899 sizeof(cblock_t)+
900 sizeof(trace_info_t)+
901 mbox_len;
903 /* put it on an even boundary */
904 if ( udp_length & 0x0001 ) {
905 udp_length += 1;
906 len += 1;
907 even_bound = 1;
910 temp = (udp_length<<8)|(udp_length>>8);
911 c_udp_pkt->udp_pkt.udp_length = temp;
913 /* swap UDP ports */
914 temp = c_udp_pkt->udp_pkt.udp_src_port;
915 c_udp_pkt->udp_pkt.udp_src_port =
916 c_udp_pkt->udp_pkt.udp_dst_port;
917 c_udp_pkt->udp_pkt.udp_dst_port = temp;
919 /* add UDP pseudo header */
920 temp = 0x1100;
921 *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound)) = temp;
922 temp = (udp_length<<8)|(udp_length>>8);
923 *((unsigned short *)(c_udp_pkt->data+mbox_len+even_bound+2)) = temp;
926 /* calculate UDP checksum */
927 c_udp_pkt->udp_pkt.udp_checksum = 0;
928 c_udp_pkt->udp_pkt.udp_checksum = calc_checksum(&data[UDP_OFFSET],udp_length+UDP_OFFSET);
930 /* fill in IP length */
931 ip_length = len;
932 temp = (ip_length<<8)|(ip_length>>8);
933 c_udp_pkt->ip_pkt.total_length = temp;
935 /* swap IP addresses */
936 ip_temp = c_udp_pkt->ip_pkt.ip_src_address;
937 c_udp_pkt->ip_pkt.ip_src_address = c_udp_pkt->ip_pkt.ip_dst_address;
938 c_udp_pkt->ip_pkt.ip_dst_address = ip_temp;
940 /* fill in IP checksum */
941 c_udp_pkt->ip_pkt.hdr_checksum = 0;
942 c_udp_pkt->ip_pkt.hdr_checksum = calc_checksum(data,sizeof(ip_pkt_t));
944 return len;
946 } /* reply_udp */
948 unsigned short calc_checksum (char *data, int len)
950 unsigned short temp;
951 unsigned long sum=0;
952 int i;
954 for( i = 0; i <len; i+=2 ) {
955 memcpy(&temp,&data[i],2);
956 sum += (unsigned long)temp;
959 while (sum >> 16 ) {
960 sum = (sum & 0xffffUL) + (sum >> 16);
963 temp = (unsigned short)sum;
964 temp = ~temp;
966 if( temp == 0 )
967 temp = 0xffff;
969 return temp;
973 /*============================================================================
974 * Get ethernet-style interface statistics.
975 * Return a pointer to struct enet_statistics.
977 static struct net_device_stats* if_stats(struct net_device* dev)
979 sdla_t *my_card;
980 chdlc_private_area_t* chdlc_priv_area;
982 /* Shutdown bug fix. In del_if() we kill
983 * dev->priv pointer. This function, gets
984 * called after del_if(), thus check
985 * if pointer has been deleted */
986 if ((chdlc_priv_area=dev->priv) == NULL)
987 return NULL;
989 my_card = chdlc_priv_area->card;
990 return &my_card->wandev.stats;
994 /****** Cisco HDLC Firmware Interface Functions *******************************/
996 /*============================================================================
997 * Read firmware code version.
998 * Put code version as ASCII string in str.
1000 static int chdlc_read_version (sdla_t* card, char* str)
1002 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1003 int len;
1004 char err;
1005 mb->buffer_length = 0;
1006 mb->command = READ_CHDLC_CODE_VERSION;
1007 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1009 if(err != COMMAND_OK) {
1010 chdlc_error(card,err,mb);
1012 else if (str) { /* is not null */
1013 len = mb->buffer_length;
1014 memcpy(str, mb->data, len);
1015 str[len] = '\0';
1017 return (err);
1020 /*-----------------------------------------------------------------------------
1021 * Configure CHDLC firmware.
1023 static int chdlc_configure (sdla_t* card, void* data)
1025 int err;
1026 CHDLC_MAILBOX_STRUCT *mailbox = card->mbox;
1027 int data_length = sizeof(CHDLC_CONFIGURATION_STRUCT);
1029 mailbox->buffer_length = data_length;
1030 memcpy(mailbox->data, data, data_length);
1031 mailbox->command = SET_CHDLC_CONFIGURATION;
1032 err = sdla_exec(mailbox) ? mailbox->return_code : CMD_TIMEOUT;
1034 if (err != COMMAND_OK) chdlc_error (card, err, mailbox);
1036 return err;
1040 /*============================================================================
1041 * Set interrupt mode -- HDLC Version.
1044 static int chdlc_set_intr_mode (sdla_t* card, unsigned mode)
1046 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1047 CHDLC_INT_TRIGGERS_STRUCT* int_data =
1048 (CHDLC_INT_TRIGGERS_STRUCT *)mb->data;
1049 int err;
1051 int_data->CHDLC_interrupt_triggers = mode;
1052 int_data->IRQ = card->hw.irq;
1053 int_data->interrupt_timer = 1;
1055 mb->buffer_length = sizeof(CHDLC_INT_TRIGGERS_STRUCT);
1056 mb->command = SET_CHDLC_INTERRUPT_TRIGGERS;
1057 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1058 if (err != COMMAND_OK)
1059 chdlc_error (card, err, mb);
1060 return err;
1064 /*============================================================================
1065 * Enable communications.
1068 static int chdlc_comm_enable (sdla_t* card)
1070 int err;
1071 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1073 mb->buffer_length = 0;
1074 mb->command = ENABLE_CHDLC_COMMUNICATIONS;
1075 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1076 if (err != COMMAND_OK)
1077 chdlc_error(card, err, mb);
1078 else
1079 card->u.c.comm_enabled=1;
1081 return err;
1084 /*============================================================================
1085 * Disable communications and Drop the Modem lines (DCD and RTS).
1087 static int chdlc_comm_disable (sdla_t* card)
1089 int err;
1090 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1092 mb->buffer_length = 0;
1093 mb->command = DISABLE_CHDLC_COMMUNICATIONS;
1094 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1095 if (err != COMMAND_OK)
1096 chdlc_error(card,err,mb);
1098 return err;
1101 /*============================================================================
1102 * Read communication error statistics.
1104 static int chdlc_read_comm_err_stats (sdla_t* card)
1106 int err;
1107 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1109 mb->buffer_length = 0;
1110 mb->command = READ_COMMS_ERROR_STATS;
1111 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1112 if (err != COMMAND_OK)
1113 chdlc_error(card,err,mb);
1114 return err;
1118 /*============================================================================
1119 * Read CHDLC operational statistics.
1121 static int chdlc_read_op_stats (sdla_t* card)
1123 int err;
1124 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1126 mb->buffer_length = 0;
1127 mb->command = READ_CHDLC_OPERATIONAL_STATS;
1128 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1129 if (err != COMMAND_OK)
1130 chdlc_error(card,err,mb);
1131 return err;
1135 /*============================================================================
1136 * Update communications error and general packet statistics.
1138 static int update_comms_stats(sdla_t* card,
1139 chdlc_private_area_t* chdlc_priv_area)
1141 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1142 COMMS_ERROR_STATS_STRUCT* err_stats;
1143 CHDLC_OPERATIONAL_STATS_STRUCT *op_stats;
1145 /* on the first timer interrupt, read the comms error statistics */
1146 if(chdlc_priv_area->update_comms_stats == 2) {
1147 if(chdlc_read_comm_err_stats(card))
1148 return 1;
1149 err_stats = (COMMS_ERROR_STATS_STRUCT *)mb->data;
1150 card->wandev.stats.rx_over_errors =
1151 err_stats->Rx_overrun_err_count;
1152 card->wandev.stats.rx_crc_errors =
1153 err_stats->CRC_err_count;
1154 card->wandev.stats.rx_frame_errors =
1155 err_stats->Rx_abort_count;
1156 card->wandev.stats.rx_fifo_errors =
1157 err_stats->Rx_dis_pri_bfrs_full_count;
1158 card->wandev.stats.rx_missed_errors =
1159 card->wandev.stats.rx_fifo_errors;
1160 card->wandev.stats.tx_aborted_errors =
1161 err_stats->sec_Tx_abort_count;
1164 /* on the second timer interrupt, read the operational statistics */
1165 else {
1166 if(chdlc_read_op_stats(card))
1167 return 1;
1168 op_stats = (CHDLC_OPERATIONAL_STATS_STRUCT *)mb->data;
1169 card->wandev.stats.rx_length_errors =
1170 (op_stats->Rx_Data_discard_short_count +
1171 op_stats->Rx_Data_discard_long_count);
1174 return 0;
1177 /*============================================================================
1178 * Send packet.
1179 * Return: 0 - o.k.
1180 * 1 - no transmit buffers available
1182 static int chdlc_send (sdla_t* card, void* data, unsigned len)
1184 CHDLC_DATA_TX_STATUS_EL_STRUCT *txbuf = card->u.c.txbuf;
1186 if (txbuf->opp_flag)
1187 return 1;
1189 sdla_poke(&card->hw, txbuf->ptr_data_bfr, data, len);
1191 txbuf->frame_length = len;
1192 txbuf->opp_flag = 1; /* start transmission */
1194 /* Update transmit buffer control fields */
1195 card->u.c.txbuf = ++txbuf;
1197 if ((void*)txbuf > card->u.c.txbuf_last)
1198 card->u.c.txbuf = card->u.c.txbuf_base;
1200 return 0;
1203 /****** Firmware Error Handler **********************************************/
1205 /*============================================================================
1206 * Firmware error handler.
1207 * This routine is called whenever firmware command returns non-zero
1208 * return code.
1210 * Return zero if previous command has to be cancelled.
1212 static int chdlc_error (sdla_t *card, int err, CHDLC_MAILBOX_STRUCT *mb)
1214 unsigned cmd = mb->command;
1216 switch (err) {
1218 case CMD_TIMEOUT:
1219 printk(KERN_ERR "%s: command 0x%02X timed out!\n",
1220 card->devname, cmd);
1221 break;
1223 case S514_BOTH_PORTS_SAME_CLK_MODE:
1224 if(cmd == SET_CHDLC_CONFIGURATION) {
1225 printk(KERN_INFO
1226 "%s: Configure both ports for the same clock source\n",
1227 card->devname);
1228 break;
1231 default:
1232 printk(KERN_INFO "%s: command 0x%02X returned 0x%02X!\n",
1233 card->devname, cmd, err);
1236 return 0;
1239 /****** Interrupt Handlers **************************************************/
1241 /*============================================================================
1242 * Cisco HDLC interrupt service routine.
1244 STATIC void wsppp_isr (sdla_t* card)
1246 struct net_device* dev;
1247 SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1248 int i;
1249 sdla_t *my_card;
1252 /* Check for which port the interrupt has been generated
1253 * Since Secondary Port is piggybacking on the Primary
1254 * the check must be done here.
1257 flags = card->u.c.flags;
1258 if (!flags->interrupt_info_struct.interrupt_type){
1259 /* Check for a second port (piggybacking) */
1260 if((my_card = card->next)){
1261 flags = my_card->u.c.flags;
1262 if (flags->interrupt_info_struct.interrupt_type){
1263 card = my_card;
1264 card->isr(card);
1265 return;
1270 dev = card->wandev.dev;
1271 card->in_isr = 1;
1272 flags = card->u.c.flags;
1274 /* If we get an interrupt with no network device, stop the interrupts
1275 * and issue an error */
1276 if ((!dev || !dev->priv) && flags->interrupt_info_struct.interrupt_type !=
1277 COMMAND_COMPLETE_APP_INT_PEND){
1278 goto isr_done;
1282 /* if critical due to peripheral operations
1283 * ie. update() or getstats() then reset the interrupt and
1284 * wait for the board to retrigger.
1286 if(test_bit(PERI_CRIT, (void*)&card->wandev.critical)) {
1287 flags->interrupt_info_struct.
1288 interrupt_type = 0;
1289 goto isr_done;
1293 /* On a 508 Card, if critical due to if_send
1294 * Major Error !!!
1296 if(card->hw.type != SDLA_S514) {
1297 if(test_bit(0, (void*)&card->wandev.critical)) {
1298 printk(KERN_INFO "%s: Critical while in ISR: %lx\n",
1299 card->devname, card->wandev.critical);
1300 goto isr_done;
1304 switch(flags->interrupt_info_struct.interrupt_type) {
1306 case RX_APP_INT_PEND: /* 0x01: receive interrupt */
1307 rx_intr(card);
1308 break;
1310 case TX_APP_INT_PEND: /* 0x02: transmit interrupt */
1311 flags->interrupt_info_struct.interrupt_permission &=
1312 ~APP_INT_ON_TX_FRAME;
1314 netif_wake_queue(dev);
1315 break;
1317 case COMMAND_COMPLETE_APP_INT_PEND:/* 0x04: cmd cplt */
1318 ++ Intr_test_counter;
1319 break;
1321 case CHDLC_EXCEP_COND_APP_INT_PEND: /* 0x20 */
1322 process_chdlc_exception(card);
1323 break;
1325 case GLOBAL_EXCEP_COND_APP_INT_PEND:
1326 process_global_exception(card);
1327 break;
1329 case TIMER_APP_INT_PEND:
1330 timer_intr(card);
1331 break;
1333 default:
1334 printk(KERN_INFO "%s: spurious interrupt 0x%02X!\n",
1335 card->devname,
1336 flags->interrupt_info_struct.interrupt_type);
1337 printk(KERN_INFO "Code name: ");
1338 for(i = 0; i < 4; i ++)
1339 printk(KERN_INFO "%c",
1340 flags->global_info_struct.codename[i]);
1341 printk(KERN_INFO "\nCode version: ");
1342 for(i = 0; i < 4; i ++)
1343 printk(KERN_INFO "%c",
1344 flags->global_info_struct.codeversion[i]);
1345 printk(KERN_INFO "\n");
1346 break;
1349 isr_done:
1350 card->in_isr = 0;
1351 flags->interrupt_info_struct.interrupt_type = 0;
1354 /*============================================================================
1355 * Receive interrupt handler.
1357 static void rx_intr (sdla_t* card)
1359 struct net_device *dev;
1360 chdlc_private_area_t *chdlc_priv_area;
1361 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1362 CHDLC_DATA_RX_STATUS_EL_STRUCT *rxbuf = card->u.c.rxmb;
1363 struct sk_buff *skb;
1364 unsigned len;
1365 unsigned addr = rxbuf->ptr_data_bfr;
1366 void *buf;
1367 int i,udp_type;
1369 if (rxbuf->opp_flag != 0x01) {
1370 printk(KERN_INFO
1371 "%s: corrupted Rx buffer @ 0x%X, flag = 0x%02X!\n",
1372 card->devname, (unsigned)rxbuf, rxbuf->opp_flag);
1373 printk(KERN_INFO "Code name: ");
1374 for(i = 0; i < 4; i ++)
1375 printk(KERN_INFO "%c",
1376 flags->global_info_struct.codename[i]);
1377 printk(KERN_INFO "\nCode version: ");
1378 for(i = 0; i < 4; i ++)
1379 printk(KERN_INFO "%c",
1380 flags->global_info_struct.codeversion[i]);
1381 printk(KERN_INFO "\n");
1384 /* Bug Fix: Mar 6 2000
1385 * If we get a corrupted mailbox, it measn that driver
1386 * is out of sync with the firmware. There is no recovery.
1387 * If we don't turn off all interrupts for this card
1388 * the machine will crash.
1390 printk(KERN_INFO "%s: Critical router failure ...!!!\n", card->devname);
1391 printk(KERN_INFO "Please contact Sangoma Technologies !\n");
1392 chdlc_set_intr_mode(card,0);
1393 return;
1396 dev = card->wandev.dev;
1398 if (!dev){
1399 goto rx_exit;
1402 if (!netif_running(dev)){
1403 goto rx_exit;
1406 chdlc_priv_area = dev->priv;
1408 if (rxbuf->error_flag){
1409 goto rx_exit;
1411 /* Take off two CRC bytes */
1413 if (rxbuf->frame_length < 7 || rxbuf->frame_length > 1506 ){
1414 goto rx_exit;
1417 len = rxbuf->frame_length - CRC_LENGTH;
1419 /* Allocate socket buffer */
1420 skb = dev_alloc_skb(len);
1422 if (skb == NULL) {
1423 if (net_ratelimit()){
1424 printk(KERN_INFO "%s: no socket buffers available!\n",
1425 card->devname);
1427 ++card->wandev.stats.rx_dropped;
1428 goto rx_exit;
1431 /* Copy data to the socket buffer */
1432 if((addr + len) > card->u.c.rx_top + 1) {
1433 unsigned tmp = card->u.c.rx_top - addr + 1;
1434 buf = skb_put(skb, tmp);
1435 sdla_peek(&card->hw, addr, buf, tmp);
1436 addr = card->u.c.rx_base;
1437 len -= tmp;
1440 buf = skb_put(skb, len);
1441 sdla_peek(&card->hw, addr, buf, len);
1443 skb->protocol = htons(ETH_P_WAN_PPP);
1445 card->wandev.stats.rx_packets ++;
1446 card->wandev.stats.rx_bytes += skb->len;
1447 udp_type = udp_pkt_type( skb, card );
1449 if(udp_type == UDP_CPIPE_TYPE) {
1450 if(store_udp_mgmt_pkt(UDP_PKT_FRM_NETWORK,
1451 card, skb, dev, chdlc_priv_area)) {
1452 flags->interrupt_info_struct.
1453 interrupt_permission |=
1454 APP_INT_ON_TIMER;
1456 }else{
1457 /* Pass it up the protocol stack */
1458 skb->dev = dev;
1459 skb->mac.raw = skb->data;
1460 netif_rx(skb);
1461 dev->last_rx = jiffies;
1464 rx_exit:
1465 /* Release buffer element and calculate a pointer to the next one */
1466 rxbuf->opp_flag = 0x00;
1467 card->u.c.rxmb = ++ rxbuf;
1468 if((void*)rxbuf > card->u.c.rxbuf_last){
1469 card->u.c.rxmb = card->u.c.rxbuf_base;
1473 /*============================================================================
1474 * Timer interrupt handler.
1475 * The timer interrupt is used for two purposes:
1476 * 1) Processing udp calls from 'cpipemon'.
1477 * 2) Reading board-level statistics for updating the proc file system.
1479 void timer_intr(sdla_t *card)
1481 struct net_device* dev;
1482 chdlc_private_area_t* chdlc_priv_area = NULL;
1483 SHARED_MEMORY_INFO_STRUCT* flags = NULL;
1485 dev = card->wandev.dev;
1486 chdlc_priv_area = dev->priv;
1488 if (chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_CONFIG) {
1489 if (!config_chdlc(card)){
1490 chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_CONFIG;
1494 /* process a udp call if pending */
1495 if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UDP) {
1496 process_udp_mgmt_pkt(card, dev,
1497 chdlc_priv_area);
1498 chdlc_priv_area->timer_int_enabled &= ~TMR_INT_ENABLED_UDP;
1502 /* read the communications statistics if required */
1503 if(chdlc_priv_area->timer_int_enabled & TMR_INT_ENABLED_UPDATE) {
1504 update_comms_stats(card, chdlc_priv_area);
1505 if(!(-- chdlc_priv_area->update_comms_stats)) {
1506 chdlc_priv_area->timer_int_enabled &=
1507 ~TMR_INT_ENABLED_UPDATE;
1511 /* only disable the timer interrupt if there are no udp or statistic */
1512 /* updates pending */
1513 if(!chdlc_priv_area->timer_int_enabled) {
1514 flags = card->u.c.flags;
1515 flags->interrupt_info_struct.interrupt_permission &=
1516 ~APP_INT_ON_TIMER;
1520 /*------------------------------------------------------------------------------
1521 Miscellaneous Functions
1522 - set_chdlc_config() used to set configuration options on the board
1523 ------------------------------------------------------------------------------*/
1525 static int set_chdlc_config(sdla_t* card)
1528 CHDLC_CONFIGURATION_STRUCT cfg;
1530 memset(&cfg, 0, sizeof(CHDLC_CONFIGURATION_STRUCT));
1532 if(card->wandev.clocking)
1533 cfg.baud_rate = card->wandev.bps;
1535 cfg.line_config_options = (card->wandev.interface == WANOPT_RS232) ?
1536 INTERFACE_LEVEL_RS232 : INTERFACE_LEVEL_V35;
1538 cfg.modem_config_options = 0;
1539 //API OPTIONS
1540 cfg.CHDLC_API_options = DISCARD_RX_ERROR_FRAMES;
1541 cfg.modem_status_timer = 100;
1542 cfg.CHDLC_protocol_options = HDLC_STREAMING_MODE;
1543 cfg.percent_data_buffer_for_Tx = 50;
1544 cfg.CHDLC_statistics_options = (CHDLC_TX_DATA_BYTE_COUNT_STAT |
1545 CHDLC_RX_DATA_BYTE_COUNT_STAT);
1546 cfg.max_CHDLC_data_field_length = card->wandev.mtu;
1548 cfg.transmit_keepalive_timer = 0;
1549 cfg.receive_keepalive_timer = 0;
1550 cfg.keepalive_error_tolerance = 0;
1551 cfg.SLARP_request_timer = 0;
1553 cfg.IP_address = 0;
1554 cfg.IP_netmask = 0;
1556 return chdlc_configure(card, &cfg);
1559 /*============================================================================
1560 * Process global exception condition
1562 static int process_global_exception(sdla_t *card)
1564 CHDLC_MAILBOX_STRUCT* mbox = card->mbox;
1565 int err;
1567 mbox->buffer_length = 0;
1568 mbox->command = READ_GLOBAL_EXCEPTION_CONDITION;
1569 err = sdla_exec(mbox) ? mbox->return_code : CMD_TIMEOUT;
1571 if(err != CMD_TIMEOUT ){
1573 switch(mbox->return_code) {
1575 case EXCEP_MODEM_STATUS_CHANGE:
1577 printk(KERN_INFO "%s: Modem status change\n",
1578 card->devname);
1580 switch(mbox->data[0] & (DCD_HIGH | CTS_HIGH)) {
1581 case (DCD_HIGH):
1582 printk(KERN_INFO "%s: DCD high, CTS low\n",card->devname);
1583 break;
1584 case (CTS_HIGH):
1585 printk(KERN_INFO "%s: DCD low, CTS high\n",card->devname);
1586 break;
1587 case ((DCD_HIGH | CTS_HIGH)):
1588 printk(KERN_INFO "%s: DCD high, CTS high\n",card->devname);
1589 break;
1590 default:
1591 printk(KERN_INFO "%s: DCD low, CTS low\n",card->devname);
1592 break;
1595 if (!(mbox->data[0] & DCD_HIGH) || !(mbox->data[0] & DCD_HIGH)){
1596 //printk(KERN_INFO "Sending TERM Request Manually !\n");
1597 send_ppp_term_request(card->wandev.dev);
1599 break;
1601 case EXCEP_TRC_DISABLED:
1602 printk(KERN_INFO "%s: Line trace disabled\n",
1603 card->devname);
1604 break;
1606 case EXCEP_IRQ_TIMEOUT:
1607 printk(KERN_INFO "%s: IRQ timeout occurred\n",
1608 card->devname);
1609 break;
1611 default:
1612 printk(KERN_INFO "%s: Global exception %x\n",
1613 card->devname, mbox->return_code);
1614 break;
1617 return 0;
1621 /*============================================================================
1622 * Process chdlc exception condition
1624 static int process_chdlc_exception(sdla_t *card)
1626 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
1627 int err;
1629 mb->buffer_length = 0;
1630 mb->command = READ_CHDLC_EXCEPTION_CONDITION;
1631 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1632 if(err != CMD_TIMEOUT) {
1634 switch (err) {
1636 case EXCEP_LINK_ACTIVE:
1637 port_set_state(card, WAN_CONNECTED);
1638 break;
1640 case EXCEP_LINK_INACTIVE_MODEM:
1641 port_set_state(card, WAN_DISCONNECTED);
1642 break;
1644 case EXCEP_LOOPBACK_CONDITION:
1645 printk(KERN_INFO "%s: Loopback Condition Detected.\n",
1646 card->devname);
1647 break;
1649 case NO_CHDLC_EXCEP_COND_TO_REPORT:
1650 printk(KERN_INFO "%s: No exceptions reported.\n",
1651 card->devname);
1652 break;
1653 default:
1654 printk(KERN_INFO "%s: Exception Condition %x!\n",
1655 card->devname,err);
1656 break;
1660 return 0;
1664 /*=============================================================================
1665 * Store a UDP management packet for later processing.
1668 static int store_udp_mgmt_pkt(char udp_pkt_src, sdla_t* card,
1669 struct sk_buff *skb, struct net_device* dev,
1670 chdlc_private_area_t* chdlc_priv_area )
1672 int udp_pkt_stored = 0;
1674 if(!chdlc_priv_area->udp_pkt_lgth &&
1675 (skb->len <= MAX_LGTH_UDP_MGNT_PKT)) {
1676 chdlc_priv_area->udp_pkt_lgth = skb->len;
1677 chdlc_priv_area->udp_pkt_src = udp_pkt_src;
1678 memcpy(chdlc_priv_area->udp_pkt_data, skb->data, skb->len);
1679 chdlc_priv_area->timer_int_enabled = TMR_INT_ENABLED_UDP;
1680 udp_pkt_stored = 1;
1683 if(udp_pkt_src == UDP_PKT_FRM_STACK)
1684 dev_kfree_skb_any(skb);
1685 else
1686 dev_kfree_skb_any(skb);
1688 return(udp_pkt_stored);
1692 /*=============================================================================
1693 * Process UDP management packet.
1696 static int process_udp_mgmt_pkt(sdla_t* card, struct net_device* dev,
1697 chdlc_private_area_t* chdlc_priv_area )
1699 unsigned char *buf;
1700 unsigned int frames, len;
1701 struct sk_buff *new_skb;
1702 unsigned short buffer_length, real_len;
1703 unsigned long data_ptr;
1704 unsigned data_length;
1705 int udp_mgmt_req_valid = 1;
1706 CHDLC_MAILBOX_STRUCT *mb = card->mbox;
1707 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
1708 chdlc_udp_pkt_t *chdlc_udp_pkt;
1709 struct timeval tv;
1710 int err;
1711 char ut_char;
1713 chdlc_udp_pkt = (chdlc_udp_pkt_t *) chdlc_priv_area->udp_pkt_data;
1715 if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
1717 switch(chdlc_udp_pkt->cblock.command) {
1718 case READ_GLOBAL_STATISTICS:
1719 case READ_MODEM_STATUS:
1720 case READ_CHDLC_LINK_STATUS:
1721 case CPIPE_ROUTER_UP_TIME:
1722 case READ_COMMS_ERROR_STATS:
1723 case READ_CHDLC_OPERATIONAL_STATS:
1725 /* These two commands are executed for
1726 * each request */
1727 case READ_CHDLC_CONFIGURATION:
1728 case READ_CHDLC_CODE_VERSION:
1729 udp_mgmt_req_valid = 1;
1730 break;
1731 default:
1732 udp_mgmt_req_valid = 0;
1733 break;
1737 if(!udp_mgmt_req_valid) {
1739 /* set length to 0 */
1740 chdlc_udp_pkt->cblock.buffer_length = 0;
1742 /* set return code */
1743 chdlc_udp_pkt->cblock.return_code = 0xCD;
1745 if (net_ratelimit()){
1746 printk(KERN_INFO
1747 "%s: Warning, Illegal UDP command attempted from network: %x\n",
1748 card->devname,chdlc_udp_pkt->cblock.command);
1751 } else {
1752 unsigned long trace_status_cfg_addr = 0;
1753 TRACE_STATUS_EL_CFG_STRUCT trace_cfg_struct;
1754 TRACE_STATUS_ELEMENT_STRUCT trace_element_struct;
1756 switch(chdlc_udp_pkt->cblock.command) {
1758 case CPIPE_ENABLE_TRACING:
1759 if (!chdlc_priv_area->TracingEnabled) {
1761 /* OPERATE_DATALINE_MONITOR */
1763 mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
1764 mb->command = SET_TRACE_CONFIGURATION;
1766 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
1767 trace_config = TRACE_ACTIVE;
1768 /* Trace delay mode is not used because it slows
1769 down transfer and results in a standoff situation
1770 when there is a lot of data */
1772 /* Configure the Trace based on user inputs */
1773 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->trace_config |=
1774 chdlc_udp_pkt->data[0];
1776 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
1777 trace_deactivation_timer = 4000;
1780 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1781 if (err != COMMAND_OK) {
1782 chdlc_error(card,err,mb);
1783 card->TracingEnabled = 0;
1784 chdlc_udp_pkt->cblock.return_code = err;
1785 mb->buffer_length = 0;
1786 break;
1789 /* Get the base address of the trace element list */
1790 mb->buffer_length = 0;
1791 mb->command = READ_TRACE_CONFIGURATION;
1792 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1794 if (err != COMMAND_OK) {
1795 chdlc_error(card,err,mb);
1796 chdlc_priv_area->TracingEnabled = 0;
1797 chdlc_udp_pkt->cblock.return_code = err;
1798 mb->buffer_length = 0;
1799 break;
1802 trace_status_cfg_addr =((LINE_TRACE_CONFIG_STRUCT *)
1803 mb->data) -> ptr_trace_stat_el_cfg_struct;
1805 sdla_peek(&card->hw, trace_status_cfg_addr,
1806 &trace_cfg_struct, sizeof(trace_cfg_struct));
1808 chdlc_priv_area->start_trace_addr = trace_cfg_struct.
1809 base_addr_trace_status_elements;
1811 chdlc_priv_area->number_trace_elements =
1812 trace_cfg_struct.number_trace_status_elements;
1814 chdlc_priv_area->end_trace_addr = (unsigned long)
1815 ((TRACE_STATUS_ELEMENT_STRUCT *)
1816 chdlc_priv_area->start_trace_addr +
1817 (chdlc_priv_area->number_trace_elements - 1));
1819 chdlc_priv_area->base_addr_trace_buffer =
1820 trace_cfg_struct.base_addr_trace_buffer;
1822 chdlc_priv_area->end_addr_trace_buffer =
1823 trace_cfg_struct.end_addr_trace_buffer;
1825 chdlc_priv_area->curr_trace_addr =
1826 trace_cfg_struct.next_trace_element_to_use;
1828 chdlc_priv_area->available_buffer_space = 2000 -
1829 sizeof(ip_pkt_t) -
1830 sizeof(udp_pkt_t) -
1831 sizeof(wp_mgmt_t) -
1832 sizeof(cblock_t) -
1833 sizeof(trace_info_t);
1835 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1836 mb->buffer_length = 0;
1837 chdlc_priv_area->TracingEnabled = 1;
1838 break;
1841 case CPIPE_DISABLE_TRACING:
1842 if (chdlc_priv_area->TracingEnabled) {
1844 /* OPERATE_DATALINE_MONITOR */
1845 mb->buffer_length = sizeof(LINE_TRACE_CONFIG_STRUCT);
1846 mb->command = SET_TRACE_CONFIGURATION;
1847 ((LINE_TRACE_CONFIG_STRUCT *)mb->data)->
1848 trace_config = TRACE_INACTIVE;
1849 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
1852 chdlc_priv_area->TracingEnabled = 0;
1853 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1854 mb->buffer_length = 0;
1855 break;
1858 case CPIPE_GET_TRACE_INFO:
1860 if (!chdlc_priv_area->TracingEnabled) {
1861 chdlc_udp_pkt->cblock.return_code = 1;
1862 mb->buffer_length = 0;
1863 break;
1866 chdlc_udp_pkt->trace_info.ismoredata = 0x00;
1867 buffer_length = 0; /* offset of packet already occupied */
1869 for (frames=0; frames < chdlc_priv_area->number_trace_elements; frames++){
1871 trace_pkt_t *trace_pkt = (trace_pkt_t *)
1872 &chdlc_udp_pkt->data[buffer_length];
1874 sdla_peek(&card->hw, chdlc_priv_area->curr_trace_addr,
1875 (unsigned char *)&trace_element_struct,
1876 sizeof(TRACE_STATUS_ELEMENT_STRUCT));
1878 if (trace_element_struct.opp_flag == 0x00) {
1879 break;
1882 /* get pointer to real data */
1883 data_ptr = trace_element_struct.ptr_data_bfr;
1885 /* See if there is actual data on the trace buffer */
1886 if (data_ptr){
1887 data_length = trace_element_struct.trace_length;
1888 }else{
1889 data_length = 0;
1890 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
1893 if( (chdlc_priv_area->available_buffer_space - buffer_length)
1894 < ( sizeof(trace_pkt_t) + data_length) ) {
1896 /* indicate there are more frames on board & exit */
1897 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
1898 break;
1901 trace_pkt->status = trace_element_struct.trace_type;
1903 trace_pkt->time_stamp =
1904 trace_element_struct.trace_time_stamp;
1906 trace_pkt->real_length =
1907 trace_element_struct.trace_length;
1909 /* see if we can fit the frame into the user buffer */
1910 real_len = trace_pkt->real_length;
1912 if (data_ptr == 0) {
1913 trace_pkt->data_avail = 0x00;
1914 } else {
1915 unsigned tmp = 0;
1917 /* get the data from circular buffer
1918 must check for end of buffer */
1919 trace_pkt->data_avail = 0x01;
1921 if ((data_ptr + real_len) >
1922 chdlc_priv_area->end_addr_trace_buffer + 1){
1924 tmp = chdlc_priv_area->end_addr_trace_buffer - data_ptr + 1;
1925 sdla_peek(&card->hw, data_ptr,
1926 trace_pkt->data,tmp);
1927 data_ptr = chdlc_priv_area->base_addr_trace_buffer;
1930 sdla_peek(&card->hw, data_ptr,
1931 &trace_pkt->data[tmp], real_len - tmp);
1934 /* zero the opp flag to show we got the frame */
1935 ut_char = 0x00;
1936 sdla_poke(&card->hw, chdlc_priv_area->curr_trace_addr, &ut_char, 1);
1938 /* now move onto the next frame */
1939 chdlc_priv_area->curr_trace_addr += sizeof(TRACE_STATUS_ELEMENT_STRUCT);
1941 /* check if we went over the last address */
1942 if ( chdlc_priv_area->curr_trace_addr > chdlc_priv_area->end_trace_addr ) {
1943 chdlc_priv_area->curr_trace_addr = chdlc_priv_area->start_trace_addr;
1946 if(trace_pkt->data_avail == 0x01) {
1947 buffer_length += real_len - 1;
1950 /* for the header */
1951 buffer_length += sizeof(trace_pkt_t);
1953 } /* For Loop */
1955 if (frames == chdlc_priv_area->number_trace_elements){
1956 chdlc_udp_pkt->trace_info.ismoredata = 0x01;
1958 chdlc_udp_pkt->trace_info.num_frames = frames;
1960 mb->buffer_length = buffer_length;
1961 chdlc_udp_pkt->cblock.buffer_length = buffer_length;
1963 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1965 break;
1968 case CPIPE_FT1_READ_STATUS:
1969 ((unsigned char *)chdlc_udp_pkt->data )[0] =
1970 flags->FT1_info_struct.parallel_port_A_input;
1972 ((unsigned char *)chdlc_udp_pkt->data )[1] =
1973 flags->FT1_info_struct.parallel_port_B_input;
1975 chdlc_udp_pkt->cblock.return_code = COMMAND_OK;
1976 mb->buffer_length = 2;
1977 break;
1979 case CPIPE_ROUTER_UP_TIME:
1980 do_gettimeofday( &tv );
1981 chdlc_priv_area->router_up_time = tv.tv_sec -
1982 chdlc_priv_area->router_start_time;
1983 *(unsigned long *)&chdlc_udp_pkt->data =
1984 chdlc_priv_area->router_up_time;
1985 mb->buffer_length = sizeof(unsigned long);
1986 break;
1988 case FT1_MONITOR_STATUS_CTRL:
1989 /* Enable FT1 MONITOR STATUS */
1990 if ((chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_STATUS) ||
1991 (chdlc_udp_pkt->data[0] & ENABLE_READ_FT1_OP_STATS)) {
1993 if( rCount++ != 0 ) {
1994 chdlc_udp_pkt->cblock.
1995 return_code = COMMAND_OK;
1996 mb->buffer_length = 1;
1997 break;
2001 /* Disable FT1 MONITOR STATUS */
2002 if( chdlc_udp_pkt->data[0] == 0) {
2004 if( --rCount != 0) {
2005 chdlc_udp_pkt->cblock.
2006 return_code = COMMAND_OK;
2007 mb->buffer_length = 1;
2008 break;
2012 default:
2013 /* it's a board command */
2014 mb->command = chdlc_udp_pkt->cblock.command;
2015 mb->buffer_length = chdlc_udp_pkt->cblock.buffer_length;
2016 if (mb->buffer_length) {
2017 memcpy(&mb->data, (unsigned char *) chdlc_udp_pkt->
2018 data, mb->buffer_length);
2020 /* run the command on the board */
2021 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2022 if (err != COMMAND_OK) {
2023 break;
2026 /* copy the result back to our buffer */
2027 memcpy(&chdlc_udp_pkt->cblock, mb, sizeof(cblock_t));
2029 if (mb->buffer_length) {
2030 memcpy(&chdlc_udp_pkt->data, &mb->data,
2031 mb->buffer_length);
2034 } /* end of switch */
2035 } /* end of else */
2037 /* Fill UDP TTL */
2038 chdlc_udp_pkt->ip_pkt.ttl = card->wandev.ttl;
2040 len = reply_udp(chdlc_priv_area->udp_pkt_data, mb->buffer_length);
2042 if(chdlc_priv_area->udp_pkt_src == UDP_PKT_FRM_NETWORK) {
2043 if(!chdlc_send(card, chdlc_priv_area->udp_pkt_data, len)) {
2044 ++ card->wandev.stats.tx_packets;
2045 card->wandev.stats.tx_bytes += len;
2047 } else {
2049 /* Pass it up the stack
2050 Allocate socket buffer */
2051 if ((new_skb = dev_alloc_skb(len)) != NULL) {
2052 /* copy data into new_skb */
2054 buf = skb_put(new_skb, len);
2055 memcpy(buf, chdlc_priv_area->udp_pkt_data, len);
2057 /* Decapsulate pkt and pass it up the protocol stack */
2058 new_skb->protocol = htons(ETH_P_IP);
2059 new_skb->dev = dev;
2060 new_skb->mac.raw = new_skb->data;
2062 netif_rx(new_skb);
2063 dev->last_rx = jiffies;
2064 } else {
2066 printk(KERN_INFO "%s: no socket buffers available!\n",
2067 card->devname);
2071 chdlc_priv_area->udp_pkt_lgth = 0;
2073 return 0;
2076 /*============================================================================
2077 * Initialize Receive and Transmit Buffers.
2080 static void init_chdlc_tx_rx_buff(sdla_t* card, struct net_device *dev)
2082 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2083 CHDLC_TX_STATUS_EL_CFG_STRUCT *tx_config;
2084 CHDLC_RX_STATUS_EL_CFG_STRUCT *rx_config;
2085 char err;
2087 mb->buffer_length = 0;
2088 mb->command = READ_CHDLC_CONFIGURATION;
2089 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2091 if(err != COMMAND_OK) {
2092 chdlc_error(card,err,mb);
2093 return;
2096 if(card->hw.type == SDLA_S514) {
2097 tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
2098 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
2099 ptr_CHDLC_Tx_stat_el_cfg_struct));
2100 rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
2101 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
2102 ptr_CHDLC_Rx_stat_el_cfg_struct));
2104 /* Setup Head and Tails for buffers */
2105 card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
2106 tx_config->base_addr_Tx_status_elements);
2107 card->u.c.txbuf_last =
2108 (CHDLC_DATA_TX_STATUS_EL_STRUCT *)
2109 card->u.c.txbuf_base +
2110 (tx_config->number_Tx_status_elements - 1);
2112 card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
2113 rx_config->base_addr_Rx_status_elements);
2114 card->u.c.rxbuf_last =
2115 (CHDLC_DATA_RX_STATUS_EL_STRUCT *)
2116 card->u.c.rxbuf_base +
2117 (rx_config->number_Rx_status_elements - 1);
2119 /* Set up next pointer to be used */
2120 card->u.c.txbuf = (void *)(card->hw.dpmbase +
2121 tx_config->next_Tx_status_element_to_use);
2122 card->u.c.rxmb = (void *)(card->hw.dpmbase +
2123 rx_config->next_Rx_status_element_to_use);
2125 else {
2126 tx_config = (CHDLC_TX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
2127 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
2128 ptr_CHDLC_Tx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
2130 rx_config = (CHDLC_RX_STATUS_EL_CFG_STRUCT *)(card->hw.dpmbase +
2131 (((CHDLC_CONFIGURATION_STRUCT *)mb->data)->
2132 ptr_CHDLC_Rx_stat_el_cfg_struct % SDLA_WINDOWSIZE));
2134 /* Setup Head and Tails for buffers */
2135 card->u.c.txbuf_base = (void *)(card->hw.dpmbase +
2136 (tx_config->base_addr_Tx_status_elements % SDLA_WINDOWSIZE));
2137 card->u.c.txbuf_last =
2138 (CHDLC_DATA_TX_STATUS_EL_STRUCT *)card->u.c.txbuf_base
2139 + (tx_config->number_Tx_status_elements - 1);
2140 card->u.c.rxbuf_base = (void *)(card->hw.dpmbase +
2141 (rx_config->base_addr_Rx_status_elements % SDLA_WINDOWSIZE));
2142 card->u.c.rxbuf_last =
2143 (CHDLC_DATA_RX_STATUS_EL_STRUCT *)card->u.c.rxbuf_base
2144 + (rx_config->number_Rx_status_elements - 1);
2146 /* Set up next pointer to be used */
2147 card->u.c.txbuf = (void *)(card->hw.dpmbase +
2148 (tx_config->next_Tx_status_element_to_use % SDLA_WINDOWSIZE));
2149 card->u.c.rxmb = (void *)(card->hw.dpmbase +
2150 (rx_config->next_Rx_status_element_to_use % SDLA_WINDOWSIZE));
2153 /* Setup Actual Buffer Start and end addresses */
2154 card->u.c.rx_base = rx_config->base_addr_Rx_buffer;
2155 card->u.c.rx_top = rx_config->end_addr_Rx_buffer;
2159 /*=============================================================================
2160 * Perform Interrupt Test by running READ_CHDLC_CODE_VERSION command MAX_INTR
2161 * _TEST_COUNTER times.
2163 static int intr_test( sdla_t* card)
2165 CHDLC_MAILBOX_STRUCT* mb = card->mbox;
2166 int err,i;
2168 Intr_test_counter = 0;
2170 /* The critical flag is unset because during initialization (if_open)
2171 * we want the interrupts to be enabled so that when the wpc_isr is
2172 * called it does not exit due to critical flag set.
2175 err = chdlc_set_intr_mode(card, APP_INT_ON_COMMAND_COMPLETE);
2177 if (err == CMD_OK) {
2178 for (i = 0; i < MAX_INTR_TEST_COUNTER; i ++) {
2179 mb->buffer_length = 0;
2180 mb->command = READ_CHDLC_CODE_VERSION;
2181 err = sdla_exec(mb) ? mb->return_code : CMD_TIMEOUT;
2184 else {
2185 return err;
2188 err = chdlc_set_intr_mode(card, 0);
2190 if (err != CMD_OK)
2191 return err;
2193 return 0;
2196 /*==============================================================================
2197 * Determine what type of UDP call it is. CPIPEAB ?
2199 static int udp_pkt_type(struct sk_buff *skb, sdla_t* card)
2201 chdlc_udp_pkt_t *chdlc_udp_pkt = (chdlc_udp_pkt_t *)skb->data;
2203 if (!strncmp(chdlc_udp_pkt->wp_mgmt.signature,UDPMGMT_SIGNATURE,8) &&
2204 (chdlc_udp_pkt->udp_pkt.udp_dst_port == ntohs(card->wandev.udp_port)) &&
2205 (chdlc_udp_pkt->ip_pkt.protocol == UDPMGMT_UDP_PROTOCOL) &&
2206 (chdlc_udp_pkt->wp_mgmt.request_reply == UDPMGMT_REQUEST)) {
2207 return UDP_CPIPE_TYPE;
2209 else return UDP_INVALID_TYPE;
2212 /*============================================================================
2213 * Set PORT state.
2215 static void port_set_state (sdla_t *card, int state)
2217 struct net_device *dev = card->wandev.dev;
2218 chdlc_private_area_t *chdlc_priv_area = dev->priv;
2220 if (card->u.c.state != state)
2222 switch (state)
2224 case WAN_CONNECTED:
2225 printk (KERN_INFO "%s: HDLC link connected!\n",
2226 card->devname);
2227 break;
2229 case WAN_CONNECTING:
2230 printk (KERN_INFO "%s: HDLC link connecting...\n",
2231 card->devname);
2232 break;
2234 case WAN_DISCONNECTED:
2235 printk (KERN_INFO "%s: HDLC link disconnected!\n",
2236 card->devname);
2237 break;
2240 card->wandev.state = card->u.c.state = state;
2241 chdlc_priv_area->common.state = state;
2245 void s508_lock (sdla_t *card, unsigned long *smp_flags)
2247 spin_lock_irqsave(&card->wandev.lock, *smp_flags);
2248 if (card->next){
2249 /* It is ok to use spin_lock here, since we
2250 * already turned off interrupts */
2251 spin_lock(&card->next->wandev.lock);
2255 void s508_unlock (sdla_t *card, unsigned long *smp_flags)
2257 if (card->next){
2258 spin_unlock(&card->next->wandev.lock);
2260 spin_unlock_irqrestore(&card->wandev.lock, *smp_flags);
2265 /*===========================================================================
2266 * config_chdlc
2268 * Configure the chdlc protocol and enable communications.
2270 * The if_open() function binds this function to the poll routine.
2271 * Therefore, this function will run every time the chdlc interface
2272 * is brought up. We cannot run this function from the if_open
2273 * because if_open does not have access to the remote IP address.
2275 * If the communications are not enabled, proceed to configure
2276 * the card and enable communications.
2278 * If the communications are enabled, it means that the interface
2279 * was shutdown by ether the user or driver. In this case, we
2280 * have to check that the IP addresses have not changed. If
2281 * the IP addresses have changed, we have to reconfigure the firmware
2282 * and update the changed IP addresses. Otherwise, just exit.
2286 static int config_chdlc (sdla_t *card)
2288 struct net_device *dev = card->wandev.dev;
2289 SHARED_MEMORY_INFO_STRUCT *flags = card->u.c.flags;
2291 if (card->u.c.comm_enabled){
2292 chdlc_comm_disable(card);
2293 port_set_state(card, WAN_DISCONNECTED);
2296 if (set_chdlc_config(card)) {
2297 printk(KERN_INFO "%s: CHDLC Configuration Failed!\n",
2298 card->devname);
2299 return 0;
2301 init_chdlc_tx_rx_buff(card, dev);
2303 /* Set interrupt mode and mask */
2304 if (chdlc_set_intr_mode(card, APP_INT_ON_RX_FRAME |
2305 APP_INT_ON_GLOBAL_EXCEP_COND |
2306 APP_INT_ON_TX_FRAME |
2307 APP_INT_ON_CHDLC_EXCEP_COND | APP_INT_ON_TIMER)){
2308 printk (KERN_INFO "%s: Failed to set interrupt triggers!\n",
2309 card->devname);
2310 return 0;
2314 /* Mask the Transmit and Timer interrupt */
2315 flags->interrupt_info_struct.interrupt_permission &=
2316 ~(APP_INT_ON_TX_FRAME | APP_INT_ON_TIMER);
2319 if (chdlc_comm_enable(card) != 0) {
2320 printk(KERN_INFO "%s: Failed to enable chdlc communications!\n",
2321 card->devname);
2322 flags->interrupt_info_struct.interrupt_permission = 0;
2323 card->u.c.comm_enabled=0;
2324 chdlc_set_intr_mode(card,0);
2325 return 0;
2328 /* Initialize Rx/Tx buffer control fields */
2329 port_set_state(card, WAN_CONNECTING);
2330 return 0;
2334 static void send_ppp_term_request(struct net_device *dev)
2336 struct sk_buff *new_skb;
2337 unsigned char *buf;
2339 if ((new_skb = dev_alloc_skb(8)) != NULL) {
2340 /* copy data into new_skb */
2342 buf = skb_put(new_skb, 8);
2343 sprintf(buf,"%c%c%c%c%c%c%c%c", 0xFF,0x03,0xC0,0x21,0x05,0x98,0x00,0x07);
2345 /* Decapsulate pkt and pass it up the protocol stack */
2346 new_skb->protocol = htons(ETH_P_WAN_PPP);
2347 new_skb->dev = dev;
2348 new_skb->mac.raw = new_skb->data;
2350 netif_rx(new_skb);
2351 dev->last_rx = jiffies;
2356 MODULE_LICENSE("GPL");
2358 /****** End ****************************************************************/