1 /*****************************************************************************
2 * sdlamain.c WANPIPE(tm) Multiprotocol WAN Link Driver. Main module.
4 * Author: Gene Kozin <genek@compuserve.com>
5 * Jaspreet Singh <jaspreet@sangoma.com>
6 * Fixes: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
8 * Copyright: (c) 1995-1997 Sangoma Technologies Inc.
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version
13 * 2 of the License, or (at your option) any later version.
14 * ============================================================================
15 * May 19, 1999 Arnaldo Melo __init for wanpipe_init
16 * Nov 28, 1997 Jaspreet Singh Changed DRV_RELEASE to 1
17 * Nov 10, 1997 Jaspreet Singh Changed sti() to restore_flags();
18 * Nov 06, 1997 Jaspreet Singh Changed DRV_VERSION to 4 and DRV_RELEASE to 0
19 * Oct 20, 1997 Jaspreet Singh Modified sdla_isr routine so that card->in_isr
20 * assignments are taken out and placed in the
21 * sdla_ppp.c, sdla_fr.c and sdla_x25.c isr
22 * routines. Took out 'wandev->tx_int_enabled' and
23 * replaced it with 'wandev->enable_tx_int'.
24 * May 29, 1997 Jaspreet Singh Flow Control Problem
25 * added "wandev->tx_int_enabled=1" line in the
26 * init module. This line intializes the flag for
27 * preventing Interrupt disabled with device set to
29 * Jan 15, 1997 Gene Kozin Version 3.1.0
30 * o added UDP management stuff
31 * Jan 02, 1997 Gene Kozin Initial version.
32 *****************************************************************************/
34 #include <linux/config.h> /* OS configuration options */
35 #include <linux/stddef.h> /* offsetof(), etc. */
36 #include <linux/errno.h> /* return codes */
37 #include <linux/string.h> /* inline memset(), etc. */
38 #include <linux/malloc.h> /* kmalloc(), kfree() */
39 #include <linux/kernel.h> /* printk(), and other useful stuff */
40 #include <linux/module.h> /* support for loadable modules */
41 #include <linux/ioport.h> /* request_region(), release_region() */
42 #include <linux/tqueue.h> /* for kernel task queues */
43 #include <linux/wanrouter.h> /* WAN router definitions */
44 #include <linux/wanpipe.h> /* WANPIPE common user API definitions */
45 #include <asm/uaccess.h> /* kernel <-> user copy */
46 #include <asm/io.h> /* phys_to_virt() */
47 #include <linux/init.h> /* __init (when not using as a module) */
50 /****** Defines & Macros ****************************************************/
58 #define DRV_VERSION 4 /* version number */
59 #define DRV_RELEASE 1 /* release (minor version) number */
60 #define MAX_CARDS 8 /* max number of adapters */
62 #ifndef CONFIG_WANPIPE_CARDS /* configurable option */
63 #define CONFIG_WANPIPE_CARDS 1
66 #define CMD_OK 0 /* normal firmware return code */
67 #define CMD_TIMEOUT 0xFF /* firmware command timed out */
68 #define MAX_CMD_RETRY 10 /* max number of firmware retries */
70 /****** Function Prototypes *************************************************/
72 /* Module entry points */
73 int init_module (void);
74 void cleanup_module (void);
76 /* WAN link driver entry points */
77 static int setup (wan_device_t
* wandev
, wandev_conf_t
* conf
);
78 static int shutdown (wan_device_t
* wandev
);
79 static int ioctl (wan_device_t
* wandev
, unsigned cmd
, unsigned long arg
);
82 static int ioctl_dump (sdla_t
* card
, sdla_dump_t
* u_dump
);
83 static int ioctl_exec (sdla_t
* card
, sdla_exec_t
* u_exec
);
85 /* Miscellaneous functions */
86 STATIC
void sdla_isr (int irq
, void* dev_id
, struct pt_regs
*regs
);
87 STATIC
void sdla_poll (void* data
);
89 /****** Global Data **********************************************************
90 * Note: All data must be explicitly initialized!!!
94 static char drvname
[] = "wanpipe";
95 static char fullname
[] = "WANPIPE(tm) Multiprotocol Driver";
96 static char copyright
[] = "(c) 1995-1996 Sangoma Technologies Inc.";
97 static int ncards
= CONFIG_WANPIPE_CARDS
;
98 static int active
= 0; /* number of active cards */
99 static sdla_t
* card_array
= NULL
; /* adapter data space */
101 /* Task queue element for creating a 'thread' */
102 static struct tq_struct sdla_tq
=
106 &sdla_poll
, /* .routine */
110 /******* Kernel Loadable Module Entry Points ********************************/
112 /*============================================================================
113 * Module 'insert' entry point.
114 * o print announcement
115 * o allocate adapter data space
116 * o initialize static data
117 * o register all cards with WAN router
118 * o calibrate SDLA shared memory access delay.
126 int init_module (void)
128 int __init
wanpipe_init(void)
133 printk(KERN_INFO
"%s v%u.%u %s\n",
134 fullname
, DRV_VERSION
, DRV_RELEASE
, copyright
)
137 /* Verify number of cards and allocate adapter data space */
138 ncards
= min(ncards
, MAX_CARDS
);
139 ncards
= max(ncards
, 1);
140 card_array
= kmalloc(sizeof(sdla_t
) * ncards
, GFP_KERNEL
);
141 if (card_array
== NULL
)
144 memset(card_array
, 0, sizeof(sdla_t
) * ncards
);
146 /* Register adapters with WAN router */
147 for (cnt
= 0; cnt
< ncards
; ++cnt
)
149 sdla_t
* card
= &card_array
[cnt
];
150 wan_device_t
* wandev
= &card
->wandev
;
152 sprintf(card
->devname
, "%s%d", drvname
, cnt
+ 1);
153 wandev
->magic
= ROUTER_MAGIC
;
154 wandev
->name
= card
->devname
;
155 wandev
->private = card
;
156 wandev
->enable_tx_int
= 0;
157 wandev
->setup
= &setup
;
158 wandev
->shutdown
= &shutdown
;
159 wandev
->ioctl
= &ioctl
;
160 err
= register_wan_device(wandev
);
164 "%s: %s registration failed with error %d!\n",
165 drvname
, card
->devname
, err
)
171 ncards
= cnt
; /* adjust actual number of cards */
181 /*============================================================================
182 * Module 'remove' entry point.
183 * o unregister all adapters from the WAN router
184 * o release all remaining system resources
186 void cleanup_module (void)
190 for (i
= 0; i
< ncards
; ++i
)
192 sdla_t
* card
= &card_array
[i
];
193 unregister_wan_device(card
->devname
);
200 /******* WAN Device Driver Entry Points *************************************/
202 /*============================================================================
203 * Setup/confugure WAN link driver.
204 * o check adapter state
205 * o make sure firmware is present in configuration
206 * o make sure I/O port and IRQ are specified
207 * o make sure I/O region is available
208 * o allocate interrupt vector
209 * o setup SDLA hardware
210 * o call appropriate routine to perform protocol-specific initialization
211 * o mark I/O region as used
212 * o if this is the first active card, then schedule background task
214 * This function is called when router handles ROUTER_SETUP IOCTL. The
215 * configuration structure is in kernel memory (including extended data, if
219 static int setup (wan_device_t
* wandev
, wandev_conf_t
* conf
)
226 if ((wandev
== NULL
) || (wandev
->private == NULL
) || (conf
== NULL
))
229 card
= wandev
->private;
230 if (wandev
->state
!= WAN_UNCONFIGURED
)
231 return -EBUSY
; /* already configured */
233 if (!conf
->data_size
|| (conf
->data
== NULL
))
236 "%s: firmware not found in configuration data!\n",
240 if (conf
->ioport
<= 0)
243 "%s: can't configure without I/O port address!\n",
250 printk(KERN_ERR
"%s: can't configure without IRQ!\n",
255 /* Make sure I/O port region is available */
256 if (check_region(conf
->ioport
, SDLA_MAXIORANGE
))
258 printk(KERN_ERR
"%s: I/O region 0x%X - 0x%X is in use!\n",
259 wandev
->name
, conf
->ioport
,
260 conf
->ioport
+ SDLA_MAXIORANGE
);
265 irq
= (conf
->irq
== 2) ? 9 : conf
->irq
; /* IRQ2 -> IRQ9 */
266 if (request_irq(irq
, sdla_isr
, 0, wandev
->name
, card
))
268 printk(KERN_ERR
"%s: can't reserve IRQ %d!\n",
273 /* Configure hardware, load firmware, etc. */
274 memset(&card
->hw
, 0, sizeof(sdlahw_t
));
275 card
->hw
.port
= conf
->ioport
;
276 card
->hw
.irq
= (conf
->irq
== 9) ? 2 : conf
->irq
;
277 /* Compute the virtual address of the card in kernel space */
279 card
->hw
.dpmbase
= phys_to_virt(conf
->maddr
);
280 else /* But 0 means NULL */
281 card
->hw
.dpmbase
= (void *)conf
->maddr
;
283 card
->hw
.dpmsize
= SDLA_WINDOWSIZE
;
284 card
->hw
.type
= conf
->hw_opt
[0];
285 card
->hw
.pclk
= conf
->hw_opt
[1];
286 err
= sdla_setup(&card
->hw
, conf
->data
, conf
->data_size
);
293 /* Intialize WAN device data space */
296 wandev
->ioport
= card
->hw
.port
;
297 wandev
->maddr
= card
->hw
.dpmbase
;
298 wandev
->msize
= card
->hw
.dpmsize
;
299 wandev
->hw_opt
[0] = card
->hw
.type
;
300 wandev
->hw_opt
[1] = card
->hw
.pclk
;
301 wandev
->hw_opt
[2] = card
->hw
.memory
;
302 wandev
->hw_opt
[3] = card
->hw
.fwid
;
304 /* Protocol-specific initialization */
305 switch (card
->hw
.fwid
)
307 #ifdef CONFIG_WANPIPE_X25
310 err
= wpx_init(card
, conf
);
314 #ifdef CONFIG_WANPIPE_FR
317 err
= wpf_init(card
, conf
);
321 #ifdef CONFIG_WANPIPE_PPP
324 err
= wpp_init(card
, conf
);
329 printk(KERN_ERR
"%s: this firmware is not supported!\n",
336 sdla_down(&card
->hw
);
340 /* Reserve I/O region and schedule background task */
341 /* printk(KERN_INFO "about to request\n");*/
342 request_region(card
->hw
.port
, card
->hw
.io_range
, wandev
->name
);
343 /* printk(KERN_INFO "request done\n");*/
345 queue_task(&sdla_tq
, &tq_scheduler
);
347 wandev
->critical
= 0;
351 /*============================================================================
352 * Shut down WAN link driver.
353 * o shut down adapter hardware
354 * o release system resources.
356 * This function is called by the router when device is being unregistered or
357 * when it handles ROUTER_DOWN IOCTL.
359 static int shutdown (wan_device_t
* wandev
)
364 if ((wandev
== NULL
) || (wandev
->private == NULL
))
367 if (wandev
->state
== WAN_UNCONFIGURED
)
370 /* If wee are in a critical section we lose */
371 if (test_and_set_bit(0, (void*)&wandev
->critical
))
374 card
= wandev
->private;
375 wandev
->state
= WAN_UNCONFIGURED
;
378 schedule(); /* stop background thread */
380 /* printk(KERN_INFO "active now %d\n", active);
382 printk(KERN_INFO "About to call sdla_down\n");*/
383 sdla_down(&card
->hw
);
384 /* printk(KERN_INFO "sdla_down done\n");
385 printk(KERN_INFO "About to call free_irq\n");*/
386 free_irq(wandev
->irq
, card
);
387 /* printk(KERN_INFO "free_irq done\n");
388 printk(KERN_INFO "About to call release_region\n");*/
389 release_region(card
->hw
.port
, card
->hw
.io_range
);
390 /* printk(KERN_INFO "release_region done\n");*/
391 wandev
->critical
= 0;
395 /*============================================================================
396 * Driver I/O control.
398 * o perform requested action
400 * This function is called when router handles one of the reserved user
401 * IOCTLs. Note that 'arg' stil points to user address space.
403 static int ioctl (wan_device_t
* wandev
, unsigned cmd
, unsigned long arg
)
408 if ((wandev
== NULL
) || (wandev
->private == NULL
))
411 if (wandev
->state
== WAN_UNCONFIGURED
)
414 if (test_and_set_bit(0, (void*)&wandev
->critical
))
420 err
= ioctl_dump(wandev
->private, (void*)arg
);
424 err
= ioctl_exec(wandev
->private, (void*)arg
);
430 wandev
->critical
= 0;
434 /****** Driver IOCTL Hanlers ************************************************/
436 /*============================================================================
437 * Dump adapter memory to user buffer.
438 * o verify request structure
439 * o copy request structure to kernel data space
440 * o verify length/offset
441 * o verify user buffer
442 * o copy adapter memory image to user buffer
444 * Note: when dumping memory, this routine switches curent dual-port memory
445 * vector, so care must be taken to avoid racing conditions.
447 static int ioctl_dump (sdla_t
* card
, sdla_dump_t
* u_dump
)
451 unsigned long oldvec
; /* DPM window vector */
455 if(copy_from_user((void*)&dump
, (void*)u_dump
, sizeof(sdla_dump_t
)))
458 if ((dump
.magic
!= WANPIPE_MAGIC
) ||
459 (dump
.offset
+ dump
.length
> card
->hw
.memory
))
462 winsize
= card
->hw
.dpmsize
;
464 cli(); /* >>> critical section start <<< */
465 oldvec
= card
->hw
.vector
;
468 unsigned pos
= dump
.offset
% winsize
; /* current offset */
469 unsigned long vec
= dump
.offset
- pos
; /* current vector */
470 unsigned len
= (dump
.length
> (winsize
- pos
)) ?
471 (winsize
- pos
) : dump
.length
473 if (sdla_mapmem(&card
->hw
, vec
) != 0) /* relocate window */
478 /* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */
479 sti(); /* Not ideal but tough we have to do this */
480 if(copy_to_user((void *)dump
.ptr
,
481 (u8
*)card
->hw
.dpmbase
+ pos
, len
))
486 (char*)dump
.ptr
+= len
;
488 sdla_mapmem(&card
->hw
, oldvec
); /* restore DPM window position */
489 restore_flags(flags
); /* >>> critical section end <<< */
493 /*============================================================================
494 * Execute adapter firmware command.
495 * o verify request structure
496 * o copy request structure to kernel data space
497 * o call protocol-specific 'exec' function
499 static int ioctl_exec (sdla_t
* card
, sdla_exec_t
* u_exec
)
503 if (card
->exec
== NULL
)
506 if(copy_from_user((void*)&exec
, (void*)u_exec
, sizeof(sdla_exec_t
)))
508 if ((exec
.magic
!= WANPIPE_MAGIC
) || (exec
.cmd
== NULL
))
510 return card
->exec(card
, exec
.cmd
, exec
.data
);
513 /******* Miscellaneous ******************************************************/
515 /*============================================================================
516 * SDLA Interrupt Service Routine.
517 * o acknowledge SDLA hardware interrupt.
518 * o call protocol-specific interrupt service routine, if any.
520 STATIC
void sdla_isr (int irq
, void* dev_id
, struct pt_regs
*regs
)
522 #define card ((sdla_t*)dev_id)
524 if (!card
|| (card
->wandev
.state
== WAN_UNCONFIGURED
))
529 printk(KERN_WARNING
"%s: interrupt re-entrancy on IRQ %d!\n",
530 card
->devname
, card
->wandev
.irq
)
535 sdla_intack(&card
->hw
);
542 /*============================================================================
543 * SDLA polling routine.
544 * This routine simulates kernel thread to perform various housekeeping job.
546 * o for each configured device call its poll() routine
547 * o if there is at least one active card, then reschedule itself once again
549 STATIC
void sdla_poll (void* data
)
553 for (i
= 0; i
< ncards
; ++i
)
555 sdla_t
* card
= &card_array
[i
];
557 if ((card
->wandev
.state
!= WAN_UNCONFIGURED
) && card
->poll
&&
558 !card
->wandev
.critical
)
564 queue_task(&sdla_tq
, &tq_scheduler
);
567 /*============================================================================
568 * This routine is called by the protocol-specific modules when network
569 * interface is being open. The only reason we need this, is because we
570 * have to call MOD_INC_USE_COUNT, but cannot include 'module.h' where it's
571 * defined more than once into the same kernel module.
573 void wanpipe_open (sdla_t
* card
)
579 /*============================================================================
580 * This routine is called by the protocol-specific modules when network
581 * interface is being closed. The only reason we need this, is because we
582 * have to call MOD_DEC_USE_COUNT, but cannot include 'module.h' where it's
583 * defined more than once into the same kernel module.
585 void wanpipe_close (sdla_t
* card
)
591 /*============================================================================
592 * Set WAN device state.
594 void wanpipe_set_state (sdla_t
* card
, int state
)
600 if (card
->wandev
.state
!= state
)
605 printk (KERN_INFO
"%s: link connected!\n",
611 printk (KERN_INFO
"%s: link connecting...\n",
616 case WAN_DISCONNECTED
:
617 printk (KERN_INFO
"%s: link disconnected!\n",
622 card
->wandev
.state
= state
;
624 card
->state_tick
= jiffies
;
625 restore_flags(flags
);
628 /****** End *****************************************************************/