aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wan/cycx_drv.c569
-rw-r--r--drivers/net/wan/cycx_main.c346
-rw-r--r--drivers/net/wan/cycx_x25.c1602
-rw-r--r--include/linux/cyclomx.h77
-rw-r--r--include/linux/cycx_drv.h64
-rw-r--r--include/linux/wanrouter.h127
-rw-r--r--include/uapi/linux/wanrouter.h443
-rw-r--r--net/wanrouter/Kconfig27
-rw-r--r--net/wanrouter/Makefile7
-rw-r--r--net/wanrouter/patchlevel1
-rw-r--r--net/wanrouter/wanmain.c782
-rw-r--r--net/wanrouter/wanproc.c380
12 files changed, 8 insertions, 4417 deletions
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
deleted file mode 100644
index 2a3ecae67a90..000000000000
--- a/drivers/net/wan/cycx_drv.c
+++ /dev/null
@@ -1,569 +0,0 @@
1/*
2* cycx_drv.c Cyclom 2X Support Module.
3*
4* This module is a library of common hardware specific
5* functions used by the Cyclades Cyclom 2X sync card.
6*
7* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
8*
9* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
10*
11* Based on sdladrv.c by Gene Kozin <genek@compuserve.com>
12*
13* This program is free software; you can redistribute it and/or
14* modify it under the terms of the GNU General Public License
15* as published by the Free Software Foundation; either version
16* 2 of the License, or (at your option) any later version.
17* ============================================================================
18* 1999/11/11 acme set_current_state(TASK_INTERRUPTIBLE), code
19* cleanup
20* 1999/11/08 acme init_cyc2x deleted, doing nothing
21* 1999/11/06 acme back to read[bw], write[bw] and memcpy_to and
22* fromio to use dpmbase ioremaped
23* 1999/10/26 acme use isa_read[bw], isa_write[bw] & isa_memcpy_to
24* & fromio
25* 1999/10/23 acme cleanup to only supports cyclom2x: all the other
26* boards are no longer manufactured by cyclades,
27* if someone wants to support them... be my guest!
28* 1999/05/28 acme cycx_intack & cycx_intde gone for good
29* 1999/05/18 acme lots of unlogged work, submitting to Linus...
30* 1999/01/03 acme more judicious use of data types
31* 1999/01/03 acme judicious use of data types :>
32* cycx_inten trying to reset pending interrupts
33* from cyclom 2x - I think this isn't the way to
34* go, but for now...
35* 1999/01/02 acme cycx_intack ok, I think there's nothing to do
36* to ack an int in cycx_drv.c, only handle it in
37* cyx_isr (or in the other protocols: cyp_isr,
38* cyf_isr, when they get implemented.
39* Dec 31, 1998 acme cycx_data_boot & cycx_code_boot fixed, crossing
40* fingers to see x25_configure in cycx_x25.c
41* work... :)
42* Dec 26, 1998 acme load implementation fixed, seems to work! :)
43* cycx_2x_dpmbase_options with all the possible
44* DPM addresses (20).
45* cycx_intr implemented (test this!)
46* general code cleanup
47* Dec 8, 1998 Ivan Passos Cyclom-2X firmware load implementation.
48* Aug 8, 1998 acme Initial version.
49*/
50
51#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
52
53#include <linux/init.h> /* __init */
54#include <linux/module.h>
55#include <linux/kernel.h> /* printk(), and other useful stuff */
56#include <linux/stddef.h> /* offsetof(), etc. */
57#include <linux/errno.h> /* return codes */
58#include <linux/cycx_drv.h> /* API definitions */
59#include <linux/cycx_cfm.h> /* CYCX firmware module definitions */
60#include <linux/delay.h> /* udelay, msleep_interruptible */
61#include <asm/io.h> /* read[wl], write[wl], ioremap, iounmap */
62
63#define MOD_VERSION 0
64#define MOD_RELEASE 6
65
66MODULE_AUTHOR("Arnaldo Carvalho de Melo");
67MODULE_DESCRIPTION("Cyclom 2x Sync Card Driver");
68MODULE_LICENSE("GPL");
69
70/* Hardware-specific functions */
71static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len);
72static void cycx_bootcfg(struct cycx_hw *hw);
73
74static int reset_cyc2x(void __iomem *addr);
75static int detect_cyc2x(void __iomem *addr);
76
77/* Miscellaneous functions */
78static int get_option_index(const long *optlist, long optval);
79static u16 checksum(u8 *buf, u32 len);
80
81#define wait_cyc(addr) cycx_exec(addr + CMD_OFFSET)
82
83/* Global Data */
84
85/* private data */
86static const char fullname[] = "Cyclom 2X Support Module";
87static const char copyright[] =
88 "(c) 1998-2003 Arnaldo Carvalho de Melo <acme@conectiva.com.br>";
89
90/* Hardware configuration options.
91 * These are arrays of configuration options used by verification routines.
92 * The first element of each array is its size (i.e. number of options).
93 */
94static const long cyc2x_dpmbase_options[] = {
95 20,
96 0xA0000, 0xA4000, 0xA8000, 0xAC000, 0xB0000, 0xB4000, 0xB8000,
97 0xBC000, 0xC0000, 0xC4000, 0xC8000, 0xCC000, 0xD0000, 0xD4000,
98 0xD8000, 0xDC000, 0xE0000, 0xE4000, 0xE8000, 0xEC000
99};
100
101static const long cycx_2x_irq_options[] = { 7, 3, 5, 9, 10, 11, 12, 15 };
102
103/* Kernel Loadable Module Entry Points */
104/* Module 'insert' entry point.
105 * o print announcement
106 * o initialize static data
107 *
108 * Return: 0 Ok
109 * < 0 error.
110 * Context: process */
111
112static int __init cycx_drv_init(void)
113{
114 pr_info("%s v%u.%u %s\n",
115 fullname, MOD_VERSION, MOD_RELEASE, copyright);
116
117 return 0;
118}
119
120/* Module 'remove' entry point.
121 * o release all remaining system resources */
122static void cycx_drv_cleanup(void)
123{
124}
125
126/* Kernel APIs */
127/* Set up adapter.
128 * o detect adapter type
129 * o verify hardware configuration options
130 * o check for hardware conflicts
131 * o set up adapter shared memory
132 * o test adapter memory
133 * o load firmware
134 * Return: 0 ok.
135 * < 0 error */
136EXPORT_SYMBOL(cycx_setup);
137int cycx_setup(struct cycx_hw *hw, void *cfm, u32 len, unsigned long dpmbase)
138{
139 int err;
140
141 /* Verify IRQ configuration options */
142 if (!get_option_index(cycx_2x_irq_options, hw->irq)) {
143 pr_err("IRQ %d is invalid!\n", hw->irq);
144 return -EINVAL;
145 }
146
147 /* Setup adapter dual-port memory window and test memory */
148 if (!dpmbase) {
149 pr_err("you must specify the dpm address!\n");
150 return -EINVAL;
151 } else if (!get_option_index(cyc2x_dpmbase_options, dpmbase)) {
152 pr_err("memory address 0x%lX is invalid!\n", dpmbase);
153 return -EINVAL;
154 }
155
156 hw->dpmbase = ioremap(dpmbase, CYCX_WINDOWSIZE);
157 hw->dpmsize = CYCX_WINDOWSIZE;
158
159 if (!detect_cyc2x(hw->dpmbase)) {
160 pr_err("adapter Cyclom 2X not found at address 0x%lX!\n",
161 dpmbase);
162 return -EINVAL;
163 }
164
165 pr_info("found Cyclom 2X card at address 0x%lX\n", dpmbase);
166
167 /* Load firmware. If loader fails then shut down adapter */
168 err = load_cyc2x(hw, cfm, len);
169
170 if (err)
171 cycx_down(hw); /* shutdown adapter */
172
173 return err;
174}
175
176EXPORT_SYMBOL(cycx_down);
177int cycx_down(struct cycx_hw *hw)
178{
179 iounmap(hw->dpmbase);
180 return 0;
181}
182
183/* Enable interrupt generation. */
184static void cycx_inten(struct cycx_hw *hw)
185{
186 writeb(0, hw->dpmbase);
187}
188
189/* Generate an interrupt to adapter's CPU. */
190EXPORT_SYMBOL(cycx_intr);
191void cycx_intr(struct cycx_hw *hw)
192{
193 writew(0, hw->dpmbase + GEN_CYCX_INTR);
194}
195
196/* Execute Adapter Command.
197 * o Set exec flag.
198 * o Busy-wait until flag is reset. */
199EXPORT_SYMBOL(cycx_exec);
200int cycx_exec(void __iomem *addr)
201{
202 u16 i = 0;
203 /* wait till addr content is zeroed */
204
205 while (readw(addr)) {
206 udelay(1000);
207
208 if (++i > 50)
209 return -1;
210 }
211
212 return 0;
213}
214
215/* Read absolute adapter memory.
216 * Transfer data from adapter's memory to data buffer. */
217EXPORT_SYMBOL(cycx_peek);
218int cycx_peek(struct cycx_hw *hw, u32 addr, void *buf, u32 len)
219{
220 if (len == 1)
221 *(u8*)buf = readb(hw->dpmbase + addr);
222 else
223 memcpy_fromio(buf, hw->dpmbase + addr, len);
224
225 return 0;
226}
227
228/* Write Absolute Adapter Memory.
229 * Transfer data from data buffer to adapter's memory. */
230EXPORT_SYMBOL(cycx_poke);
231int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len)
232{
233 if (len == 1)
234 writeb(*(u8*)buf, hw->dpmbase + addr);
235 else
236 memcpy_toio(hw->dpmbase + addr, buf, len);
237
238 return 0;
239}
240
241/* Hardware-Specific Functions */
242
243/* Load Aux Routines */
244/* Reset board hardware.
245 return 1 if memory exists at addr and 0 if not. */
246static int memory_exists(void __iomem *addr)
247{
248 int tries = 0;
249
250 for (; tries < 3 ; tries++) {
251 writew(TEST_PATTERN, addr + 0x10);
252
253 if (readw(addr + 0x10) == TEST_PATTERN)
254 if (readw(addr + 0x10) == TEST_PATTERN)
255 return 1;
256
257 msleep_interruptible(1 * 1000);
258 }
259
260 return 0;
261}
262
263/* Load reset code. */
264static void reset_load(void __iomem *addr, u8 *buffer, u32 cnt)
265{
266 void __iomem *pt_code = addr + RESET_OFFSET;
267 u16 i; /*, j; */
268
269 for (i = 0 ; i < cnt ; i++) {
270/* for (j = 0 ; j < 50 ; j++); Delay - FIXME busy waiting... */
271 writeb(*buffer++, pt_code++);
272 }
273}
274
275/* Load buffer using boot interface.
276 * o copy data from buffer to Cyclom-X memory
277 * o wait for reset code to copy it to right portion of memory */
278static int buffer_load(void __iomem *addr, u8 *buffer, u32 cnt)
279{
280 memcpy_toio(addr + DATA_OFFSET, buffer, cnt);
281 writew(GEN_BOOT_DAT, addr + CMD_OFFSET);
282
283 return wait_cyc(addr);
284}
285
286/* Set up entry point and kick start Cyclom-X CPU. */
287static void cycx_start(void __iomem *addr)
288{
289 /* put in 0x30 offset the jump instruction to the code entry point */
290 writeb(0xea, addr + 0x30);
291 writeb(0x00, addr + 0x31);
292 writeb(0xc4, addr + 0x32);
293 writeb(0x00, addr + 0x33);
294 writeb(0x00, addr + 0x34);
295
296 /* cmd to start executing code */
297 writew(GEN_START, addr + CMD_OFFSET);
298}
299
300/* Load and boot reset code. */
301static void cycx_reset_boot(void __iomem *addr, u8 *code, u32 len)
302{
303 void __iomem *pt_start = addr + START_OFFSET;
304
305 writeb(0xea, pt_start++); /* jmp to f000:3f00 */
306 writeb(0x00, pt_start++);
307 writeb(0xfc, pt_start++);
308 writeb(0x00, pt_start++);
309 writeb(0xf0, pt_start);
310 reset_load(addr, code, len);
311
312 /* 80186 was in hold, go */
313 writeb(0, addr + START_CPU);
314 msleep_interruptible(1 * 1000);
315}
316
317/* Load data.bin file through boot (reset) interface. */
318static int cycx_data_boot(void __iomem *addr, u8 *code, u32 len)
319{
320 void __iomem *pt_boot_cmd = addr + CMD_OFFSET;
321 u32 i;
322
323 /* boot buffer length */
324 writew(CFM_LOAD_BUFSZ, pt_boot_cmd + sizeof(u16));
325 writew(GEN_DEFPAR, pt_boot_cmd);
326
327 if (wait_cyc(addr) < 0)
328 return -1;
329
330 writew(0, pt_boot_cmd + sizeof(u16));
331 writew(0x4000, pt_boot_cmd + 2 * sizeof(u16));
332 writew(GEN_SET_SEG, pt_boot_cmd);
333
334 if (wait_cyc(addr) < 0)
335 return -1;
336
337 for (i = 0 ; i < len ; i += CFM_LOAD_BUFSZ)
338 if (buffer_load(addr, code + i,
339 min_t(u32, CFM_LOAD_BUFSZ, (len - i))) < 0) {
340 pr_err("Error !!\n");
341 return -1;
342 }
343
344 return 0;
345}
346
347
348/* Load code.bin file through boot (reset) interface. */
349static int cycx_code_boot(void __iomem *addr, u8 *code, u32 len)
350{
351 void __iomem *pt_boot_cmd = addr + CMD_OFFSET;
352 u32 i;
353
354 /* boot buffer length */
355 writew(CFM_LOAD_BUFSZ, pt_boot_cmd + sizeof(u16));
356 writew(GEN_DEFPAR, pt_boot_cmd);
357
358 if (wait_cyc(addr) < 0)
359 return -1;
360
361 writew(0x0000, pt_boot_cmd + sizeof(u16));
362 writew(0xc400, pt_boot_cmd + 2 * sizeof(u16));
363 writew(GEN_SET_SEG, pt_boot_cmd);
364
365 if (wait_cyc(addr) < 0)
366 return -1;
367
368 for (i = 0 ; i < len ; i += CFM_LOAD_BUFSZ)
369 if (buffer_load(addr, code + i,
370 min_t(u32, CFM_LOAD_BUFSZ, (len - i)))) {
371 pr_err("Error !!\n");
372 return -1;
373 }
374
375 return 0;
376}
377
378/* Load adapter from the memory image of the CYCX firmware module.
379 * o verify firmware integrity and compatibility
380 * o start adapter up */
381static int load_cyc2x(struct cycx_hw *hw, struct cycx_firmware *cfm, u32 len)
382{
383 int i, j;
384 struct cycx_fw_header *img_hdr;
385 u8 *reset_image,
386 *data_image,
387 *code_image;
388 void __iomem *pt_cycld = hw->dpmbase + 0x400;
389 u16 cksum;
390
391 /* Announce */
392 pr_info("firmware signature=\"%s\"\n", cfm->signature);
393
394 /* Verify firmware signature */
395 if (strcmp(cfm->signature, CFM_SIGNATURE)) {
396 pr_err("load_cyc2x: not Cyclom-2X firmware!\n");
397 return -EINVAL;
398 }
399
400 pr_info("firmware version=%u\n", cfm->version);
401
402 /* Verify firmware module format version */
403 if (cfm->version != CFM_VERSION) {
404 pr_err("%s: firmware format %u rejected! Expecting %u.\n",
405 __func__, cfm->version, CFM_VERSION);
406 return -EINVAL;
407 }
408
409 /* Verify firmware module length and checksum */
410 cksum = checksum((u8*)&cfm->info, sizeof(struct cycx_fw_info) +
411 cfm->info.codesize);
412/*
413 FIXME cfm->info.codesize is off by 2
414 if (((len - sizeof(struct cycx_firmware) - 1) != cfm->info.codesize) ||
415*/
416 if (cksum != cfm->checksum) {
417 pr_err("%s: firmware corrupted!\n", __func__);
418 pr_err(" cdsize = 0x%x (expected 0x%lx)\n",
419 len - (int)sizeof(struct cycx_firmware) - 1,
420 cfm->info.codesize);
421 pr_err(" chksum = 0x%x (expected 0x%x)\n",
422 cksum, cfm->checksum);
423 return -EINVAL;
424 }
425
426 /* If everything is ok, set reset, data and code pointers */
427 img_hdr = (struct cycx_fw_header *)&cfm->image;
428#ifdef FIRMWARE_DEBUG
429 pr_info("%s: image sizes\n", __func__);
430 pr_info(" reset=%lu\n", img_hdr->reset_size);
431 pr_info(" data=%lu\n", img_hdr->data_size);
432 pr_info(" code=%lu\n", img_hdr->code_size);
433#endif
434 reset_image = ((u8 *)img_hdr) + sizeof(struct cycx_fw_header);
435 data_image = reset_image + img_hdr->reset_size;
436 code_image = data_image + img_hdr->data_size;
437
438 /*---- Start load ----*/
439 /* Announce */
440 pr_info("loading firmware %s (ID=%u)...\n",
441 cfm->descr[0] ? cfm->descr : "unknown firmware",
442 cfm->info.codeid);
443
444 for (i = 0 ; i < 5 ; i++) {
445 /* Reset Cyclom hardware */
446 if (!reset_cyc2x(hw->dpmbase)) {
447 pr_err("dpm problem or board not found\n");
448 return -EINVAL;
449 }
450
451 /* Load reset.bin */
452 cycx_reset_boot(hw->dpmbase, reset_image, img_hdr->reset_size);
453 /* reset is waiting for boot */
454 writew(GEN_POWER_ON, pt_cycld);
455 msleep_interruptible(1 * 1000);
456
457 for (j = 0 ; j < 3 ; j++)
458 if (!readw(pt_cycld))
459 goto reset_loaded;
460 else
461 msleep_interruptible(1 * 1000);
462 }
463
464 pr_err("reset not started\n");
465 return -EINVAL;
466
467reset_loaded:
468 /* Load data.bin */
469 if (cycx_data_boot(hw->dpmbase, data_image, img_hdr->data_size)) {
470 pr_err("cannot load data file\n");
471 return -EINVAL;
472 }
473
474 /* Load code.bin */
475 if (cycx_code_boot(hw->dpmbase, code_image, img_hdr->code_size)) {
476 pr_err("cannot load code file\n");
477 return -EINVAL;
478 }
479
480 /* Prepare boot-time configuration data */
481 cycx_bootcfg(hw);
482
483 /* kick-off CPU */
484 cycx_start(hw->dpmbase);
485
486 /* Arthur Ganzert's tip: wait a while after the firmware loading...
487 seg abr 26 17:17:12 EST 1999 - acme */
488 msleep_interruptible(7 * 1000);
489 pr_info("firmware loaded!\n");
490
491 /* enable interrupts */
492 cycx_inten(hw);
493
494 return 0;
495}
496
497/* Prepare boot-time firmware configuration data.
498 * o initialize configuration data area
499 From async.doc - V_3.4.0 - 07/18/1994
500 - As of now, only static buffers are available to the user.
501 So, the bit VD_RXDIRC must be set in 'valid'. That means that user
502 wants to use the static transmission and reception buffers. */
503static void cycx_bootcfg(struct cycx_hw *hw)
504{
505 /* use fixed buffers */
506 writeb(FIXED_BUFFERS, hw->dpmbase + CONF_OFFSET);
507}
508
509/* Detect Cyclom 2x adapter.
510 * Following tests are used to detect Cyclom 2x adapter:
511 * to be completed based on the tests done below
512 * Return 1 if detected o.k. or 0 if failed.
513 * Note: This test is destructive! Adapter will be left in shutdown
514 * state after the test. */
515static int detect_cyc2x(void __iomem *addr)
516{
517 reset_cyc2x(addr);
518
519 return memory_exists(addr);
520}
521
522/* Miscellaneous */
523/* Get option's index into the options list.
524 * Return option's index (1 .. N) or zero if option is invalid. */
525static int get_option_index(const long *optlist, long optval)
526{
527 int i = 1;
528
529 for (; i <= optlist[0]; ++i)
530 if (optlist[i] == optval)
531 return i;
532
533 return 0;
534}
535
536/* Reset adapter's CPU. */
537static int reset_cyc2x(void __iomem *addr)
538{
539 writeb(0, addr + RST_ENABLE);
540 msleep_interruptible(2 * 1000);
541 writeb(0, addr + RST_DISABLE);
542 msleep_interruptible(2 * 1000);
543
544 return memory_exists(addr);
545}
546
547/* Calculate 16-bit CRC using CCITT polynomial. */
548static u16 checksum(u8 *buf, u32 len)
549{
550 u16 crc = 0;
551 u16 mask, flag;
552
553 for (; len; --len, ++buf)
554 for (mask = 0x80; mask; mask >>= 1) {
555 flag = (crc & 0x8000);
556 crc <<= 1;
557 crc |= ((*buf & mask) ? 1 : 0);
558
559 if (flag)
560 crc ^= 0x1021;
561 }
562
563 return crc;
564}
565
566module_init(cycx_drv_init);
567module_exit(cycx_drv_cleanup);
568
569/* End */
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
deleted file mode 100644
index 81fbbad406be..000000000000
--- a/drivers/net/wan/cycx_main.c
+++ /dev/null
@@ -1,346 +0,0 @@
1/*
2* cycx_main.c Cyclades Cyclom 2X WAN Link Driver. Main module.
3*
4* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5*
6* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
7*
8* Based on sdlamain.c by Gene Kozin <genek@compuserve.com> &
9* Jaspreet Singh <jaspreet@sangoma.com>
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version
14* 2 of the License, or (at your option) any later version.
15* ============================================================================
16* Please look at the bitkeeper changelog (or any other scm tool that ends up
17* importing bitkeeper changelog or that replaces bitkeeper in the future as
18* main tool for linux development).
19*
20* 2001/05/09 acme Fix MODULE_DESC for debug, .bss nitpicks,
21* some cleanups
22* 2000/07/13 acme remove useless #ifdef MODULE and crap
23* #if KERNEL_VERSION > blah
24* 2000/07/06 acme __exit at cyclomx_cleanup
25* 2000/04/02 acme dprintk and cycx_debug
26* module_init/module_exit
27* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count
28* and cyclomx_close to cyclomx_mod_dec_use_count
29* 2000/01/08 acme cleanup
30* 1999/11/06 acme cycx_down back to life (it needs to be
31* called to iounmap the dpmbase)
32* 1999/08/09 acme removed references to enable_tx_int
33* use spinlocks instead of cli/sti in
34* cyclomx_set_state
35* 1999/05/19 acme works directly linked into the kernel
36* init_waitqueue_head for 2.3.* kernel
37* 1999/05/18 acme major cleanup (polling not needed), etc
38* 1998/08/28 acme minor cleanup (ioctls for firmware deleted)
39* queue_task activated
40* 1998/08/08 acme Initial version.
41*/
42
43#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
44
45#include <linux/stddef.h> /* offsetof(), etc. */
46#include <linux/errno.h> /* return codes */
47#include <linux/string.h> /* inline memset(), etc. */
48#include <linux/slab.h> /* kmalloc(), kfree() */
49#include <linux/kernel.h> /* printk(), and other useful stuff */
50#include <linux/module.h> /* support for loadable modules */
51#include <linux/ioport.h> /* request_region(), release_region() */
52#include <linux/wanrouter.h> /* WAN router definitions */
53#include <linux/cyclomx.h> /* cyclomx common user API definitions */
54#include <linux/init.h> /* __init (when not using as a module) */
55#include <linux/interrupt.h>
56
57unsigned int cycx_debug;
58
59MODULE_AUTHOR("Arnaldo Carvalho de Melo");
60MODULE_DESCRIPTION("Cyclom 2X Sync Card Driver.");
61MODULE_LICENSE("GPL");
62module_param(cycx_debug, int, 0);
63MODULE_PARM_DESC(cycx_debug, "cyclomx debug level");
64
65/* Defines & Macros */
66
67#define CYCX_DRV_VERSION 0 /* version number */
68#define CYCX_DRV_RELEASE 11 /* release (minor version) number */
69#define CYCX_MAX_CARDS 1 /* max number of adapters */
70
71#define CONFIG_CYCX_CARDS 1
72
73/* Function Prototypes */
74
75/* WAN link driver entry points */
76static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf);
77static int cycx_wan_shutdown(struct wan_device *wandev);
78
79/* Miscellaneous functions */
80static irqreturn_t cycx_isr(int irq, void *dev_id);
81
82/* Global Data
83 * Note: All data must be explicitly initialized!!!
84 */
85
86/* private data */
87static const char cycx_drvname[] = "cyclomx";
88static const char cycx_fullname[] = "CYCLOM 2X(tm) Sync Card Driver";
89static const char cycx_copyright[] = "(c) 1998-2003 Arnaldo Carvalho de Melo "
90 "<acme@conectiva.com.br>";
91static int cycx_ncards = CONFIG_CYCX_CARDS;
92static struct cycx_device *cycx_card_array; /* adapter data space */
93
94/* Kernel Loadable Module Entry Points */
95
96/*
97 * Module 'insert' entry point.
98 * o print announcement
99 * o allocate adapter data space
100 * o initialize static data
101 * o register all cards with WAN router
102 * o calibrate Cyclom 2X shared memory access delay.
103 *
104 * Return: 0 Ok
105 * < 0 error.
106 * Context: process
107 */
108static int __init cycx_init(void)
109{
110 int cnt, err = -ENOMEM;
111
112 pr_info("%s v%u.%u %s\n",
113 cycx_fullname, CYCX_DRV_VERSION, CYCX_DRV_RELEASE,
114 cycx_copyright);
115
116 /* Verify number of cards and allocate adapter data space */
117 cycx_ncards = min_t(int, cycx_ncards, CYCX_MAX_CARDS);
118 cycx_ncards = max_t(int, cycx_ncards, 1);
119 cycx_card_array = kcalloc(cycx_ncards, sizeof(struct cycx_device), GFP_KERNEL);
120 if (!cycx_card_array)
121 goto out;
122
123
124 /* Register adapters with WAN router */
125 for (cnt = 0; cnt < cycx_ncards; ++cnt) {
126 struct cycx_device *card = &cycx_card_array[cnt];
127 struct wan_device *wandev = &card->wandev;
128
129 sprintf(card->devname, "%s%d", cycx_drvname, cnt + 1);
130 wandev->magic = ROUTER_MAGIC;
131 wandev->name = card->devname;
132 wandev->private = card;
133 wandev->setup = cycx_wan_setup;
134 wandev->shutdown = cycx_wan_shutdown;
135 err = register_wan_device(wandev);
136
137 if (err) {
138 pr_err("%s registration failed with error %d!\n",
139 card->devname, err);
140 break;
141 }
142 }
143
144 err = -ENODEV;
145 if (!cnt) {
146 kfree(cycx_card_array);
147 goto out;
148 }
149 err = 0;
150 cycx_ncards = cnt; /* adjust actual number of cards */
151out: return err;
152}
153
154/*
155 * Module 'remove' entry point.
156 * o unregister all adapters from the WAN router
157 * o release all remaining system resources
158 */
159static void __exit cycx_exit(void)
160{
161 int i = 0;
162
163 for (; i < cycx_ncards; ++i) {
164 struct cycx_device *card = &cycx_card_array[i];
165 unregister_wan_device(card->devname);
166 }
167
168 kfree(cycx_card_array);
169}
170
171/* WAN Device Driver Entry Points */
172/*
173 * Setup/configure WAN link driver.
174 * o check adapter state
175 * o make sure firmware is present in configuration
176 * o allocate interrupt vector
177 * o setup Cyclom 2X hardware
178 * o call appropriate routine to perform protocol-specific initialization
179 *
180 * This function is called when router handles ROUTER_SETUP IOCTL. The
181 * configuration structure is in kernel memory (including extended data, if
182 * any).
183 */
184static int cycx_wan_setup(struct wan_device *wandev, wandev_conf_t *conf)
185{
186 int rc = -EFAULT;
187 struct cycx_device *card;
188 int irq;
189
190 /* Sanity checks */
191
192 if (!wandev || !wandev->private || !conf)
193 goto out;
194
195 card = wandev->private;
196 rc = -EBUSY;
197 if (wandev->state != WAN_UNCONFIGURED)
198 goto out;
199
200 rc = -EINVAL;
201 if (!conf->data_size || !conf->data) {
202 pr_err("%s: firmware not found in configuration data!\n",
203 wandev->name);
204 goto out;
205 }
206
207 if (conf->irq <= 0) {
208 pr_err("%s: can't configure without IRQ!\n", wandev->name);
209 goto out;
210 }
211
212 /* Allocate IRQ */
213 irq = conf->irq == 2 ? 9 : conf->irq; /* IRQ2 -> IRQ9 */
214
215 if (request_irq(irq, cycx_isr, 0, wandev->name, card)) {
216 pr_err("%s: can't reserve IRQ %d!\n", wandev->name, irq);
217 goto out;
218 }
219
220 /* Configure hardware, load firmware, etc. */
221 memset(&card->hw, 0, sizeof(card->hw));
222 card->hw.irq = irq;
223 card->hw.dpmsize = CYCX_WINDOWSIZE;
224 card->hw.fwid = CFID_X25_2X;
225 spin_lock_init(&card->lock);
226 init_waitqueue_head(&card->wait_stats);
227
228 rc = cycx_setup(&card->hw, conf->data, conf->data_size, conf->maddr);
229 if (rc)
230 goto out_irq;
231
232 /* Initialize WAN device data space */
233 wandev->irq = irq;
234 wandev->dma = wandev->ioport = 0;
235 wandev->maddr = (unsigned long)card->hw.dpmbase;
236 wandev->msize = card->hw.dpmsize;
237 wandev->hw_opt[2] = 0;
238 wandev->hw_opt[3] = card->hw.fwid;
239
240 /* Protocol-specific initialization */
241 switch (card->hw.fwid) {
242#ifdef CONFIG_CYCLOMX_X25
243 case CFID_X25_2X:
244 rc = cycx_x25_wan_init(card, conf);
245 break;
246#endif
247 default:
248 pr_err("%s: this firmware is not supported!\n", wandev->name);
249 rc = -EINVAL;
250 }
251
252 if (rc) {
253 cycx_down(&card->hw);
254 goto out_irq;
255 }
256
257 rc = 0;
258out:
259 return rc;
260out_irq:
261 free_irq(irq, card);
262 goto out;
263}
264
265/*
266 * Shut down WAN link driver.
267 * o shut down adapter hardware
268 * o release system resources.
269 *
270 * This function is called by the router when device is being unregistered or
271 * when it handles ROUTER_DOWN IOCTL.
272 */
273static int cycx_wan_shutdown(struct wan_device *wandev)
274{
275 int ret = -EFAULT;
276 struct cycx_device *card;
277
278 /* sanity checks */
279 if (!wandev || !wandev->private)
280 goto out;
281
282 ret = 0;
283 if (wandev->state == WAN_UNCONFIGURED)
284 goto out;
285
286 card = wandev->private;
287 wandev->state = WAN_UNCONFIGURED;
288 cycx_down(&card->hw);
289 pr_info("%s: irq %d being freed!\n", wandev->name, wandev->irq);
290 free_irq(wandev->irq, card);
291out: return ret;
292}
293
294/* Miscellaneous */
295/*
296 * Cyclom 2X Interrupt Service Routine.
297 * o acknowledge Cyclom 2X hardware interrupt.
298 * o call protocol-specific interrupt service routine, if any.
299 */
300static irqreturn_t cycx_isr(int irq, void *dev_id)
301{
302 struct cycx_device *card = dev_id;
303
304 if (card->wandev.state == WAN_UNCONFIGURED)
305 goto out;
306
307 if (card->in_isr) {
308 pr_warn("%s: interrupt re-entrancy on IRQ %d!\n",
309 card->devname, card->wandev.irq);
310 goto out;
311 }
312
313 if (card->isr)
314 card->isr(card);
315 return IRQ_HANDLED;
316out:
317 return IRQ_NONE;
318}
319
320/* Set WAN device state. */
321void cycx_set_state(struct cycx_device *card, int state)
322{
323 unsigned long flags;
324 char *string_state = NULL;
325
326 spin_lock_irqsave(&card->lock, flags);
327
328 if (card->wandev.state != state) {
329 switch (state) {
330 case WAN_CONNECTED:
331 string_state = "connected!";
332 break;
333 case WAN_DISCONNECTED:
334 string_state = "disconnected!";
335 break;
336 }
337 pr_info("%s: link %s\n", card->devname, string_state);
338 card->wandev.state = state;
339 }
340
341 card->state_tick = jiffies;
342 spin_unlock_irqrestore(&card->lock, flags);
343}
344
345module_init(cycx_init);
346module_exit(cycx_exit);
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
deleted file mode 100644
index 06f3f6309e4b..000000000000
--- a/drivers/net/wan/cycx_x25.c
+++ /dev/null
@@ -1,1602 +0,0 @@
1/*
2* cycx_x25.c Cyclom 2X WAN Link Driver. X.25 module.
3*
4* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5*
6* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
7*
8* Based on sdla_x25.c by Gene Kozin <genek@compuserve.com>
9*
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* 2001/01/12 acme use dev_kfree_skb_irq on interrupt context
16* 2000/04/02 acme dprintk, cycx_debug
17* fixed the bug introduced in get_dev_by_lcn and
18* get_dev_by_dte_addr by the anonymous hacker
19* that converted this driver to softnet
20* 2000/01/08 acme cleanup
21* 1999/10/27 acme use ARPHRD_HWX25 so that the X.25 stack know
22* that we have a X.25 stack implemented in
23* firmware onboard
24* 1999/10/18 acme support for X.25 sockets in if_send,
25* beware: socket(AF_X25...) IS WORK IN PROGRESS,
26* TCP/IP over X.25 via wanrouter not affected,
27* working.
28* 1999/10/09 acme chan_disc renamed to chan_disconnect,
29* began adding support for X.25 sockets:
30* conf->protocol in new_if
31* 1999/10/05 acme fixed return E... to return -E...
32* 1999/08/10 acme serialized access to the card thru a spinlock
33* in x25_exec
34* 1999/08/09 acme removed per channel spinlocks
35* removed references to enable_tx_int
36* 1999/05/28 acme fixed nibble_to_byte, ackvc now properly treated
37* if_send simplified
38* 1999/05/25 acme fixed t1, t2, t21 & t23 configuration
39* use spinlocks instead of cli/sti in some points
40* 1999/05/24 acme finished the x25_get_stat function
41* 1999/05/23 acme dev->type = ARPHRD_X25 (tcpdump only works,
42* AFAIT, with ARPHRD_ETHER). This seems to be
43* needed to use socket(AF_X25)...
44* Now the config file must specify a peer media
45* address for svc channels over a crossover cable.
46* Removed hold_timeout from x25_channel_t,
47* not used.
48* A little enhancement in the DEBUG processing
49* 1999/05/22 acme go to DISCONNECTED in disconnect_confirm_intr,
50* instead of chan_disc.
51* 1999/05/16 marcelo fixed timer initialization in SVCs
52* 1999/01/05 acme x25_configure now get (most of) all
53* parameters...
54* 1999/01/05 acme pktlen now (correctly) uses log2 (value
55* configured)
56* 1999/01/03 acme judicious use of data types (u8, u16, u32, etc)
57* 1999/01/03 acme cyx_isr: reset dpmbase to acknowledge
58* indication (interrupt from cyclom 2x)
59* 1999/01/02 acme cyx_isr: first hackings...
60* 1999/01/0203 acme when initializing an array don't give less
61* elements than declared...
62* example: char send_cmd[6] = "?\xFF\x10";
63* you'll gonna lose a couple hours, 'cause your
64* brain won't admit that there's an error in the
65* above declaration... the side effect is that
66* memset is put into the unresolved symbols
67* instead of using the inline memset functions...
68* 1999/01/02 acme began chan_connect, chan_send, x25_send
69* 1998/12/31 acme x25_configure
70* this code can be compiled as non module
71* 1998/12/27 acme code cleanup
72* IPX code wiped out! let's decrease code
73* complexity for now, remember: I'm learning! :)
74* bps_to_speed_code OK
75* 1998/12/26 acme Minimal debug code cleanup
76* 1998/08/08 acme Initial version.
77*/
78
79#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
80
81#define CYCLOMX_X25_DEBUG 1
82
83#include <linux/ctype.h> /* isdigit() */
84#include <linux/errno.h> /* return codes */
85#include <linux/if_arp.h> /* ARPHRD_HWX25 */
86#include <linux/kernel.h> /* printk(), and other useful stuff */
87#include <linux/module.h>
88#include <linux/string.h> /* inline memset(), etc. */
89#include <linux/sched.h>
90#include <linux/slab.h> /* kmalloc(), kfree() */
91#include <linux/stddef.h> /* offsetof(), etc. */
92#include <linux/wanrouter.h> /* WAN router definitions */
93
94#include <asm/byteorder.h> /* htons(), etc. */
95
96#include <linux/cyclomx.h> /* Cyclom 2X common user API definitions */
97#include <linux/cycx_x25.h> /* X.25 firmware API definitions */
98
99#include <net/x25device.h>
100
101/* Defines & Macros */
102#define CYCX_X25_MAX_CMD_RETRY 5
103#define CYCX_X25_CHAN_MTU 2048 /* unfragmented logical channel MTU */
104
105/* Data Structures */
106/* This is an extension of the 'struct net_device' we create for each network
107 interface to keep the rest of X.25 channel-specific data. */
108struct cycx_x25_channel {
109 /* This member must be first. */
110 struct net_device *slave; /* WAN slave */
111
112 char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
113 char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
114 char *local_addr; /* local media address, ASCIIZ -
115 svc thru crossover cable */
116 s16 lcn; /* logical channel number/conn.req.key*/
117 u8 link;
118 struct timer_list timer; /* timer used for svc channel disc. */
119 u16 protocol; /* ethertype, 0 - multiplexed */
120 u8 svc; /* 0 - permanent, 1 - switched */
121 u8 state; /* channel state */
122 u8 drop_sequence; /* mark sequence for dropping */
123 u32 idle_tmout; /* sec, before disconnecting */
124 struct sk_buff *rx_skb; /* receive socket buffer */
125 struct cycx_device *card; /* -> owner */
126 struct net_device_stats ifstats;/* interface statistics */
127};
128
129/* Function Prototypes */
130/* WAN link driver entry points. These are called by the WAN router module. */
131static int cycx_wan_update(struct wan_device *wandev),
132 cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
133 wanif_conf_t *conf),
134 cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev);
135
136/* Network device interface */
137static int cycx_netdevice_init(struct net_device *dev);
138static int cycx_netdevice_open(struct net_device *dev);
139static int cycx_netdevice_stop(struct net_device *dev);
140static int cycx_netdevice_hard_header(struct sk_buff *skb,
141 struct net_device *dev, u16 type,
142 const void *daddr, const void *saddr,
143 unsigned len);
144static int cycx_netdevice_rebuild_header(struct sk_buff *skb);
145static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
146 struct net_device *dev);
147
148static struct net_device_stats *
149 cycx_netdevice_get_stats(struct net_device *dev);
150
151/* Interrupt handlers */
152static void cycx_x25_irq_handler(struct cycx_device *card),
153 cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
154 cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd),
155 cycx_x25_irq_log(struct cycx_device *card,
156 struct cycx_x25_cmd *cmd),
157 cycx_x25_irq_stat(struct cycx_device *card,
158 struct cycx_x25_cmd *cmd),
159 cycx_x25_irq_connect_confirm(struct cycx_device *card,
160 struct cycx_x25_cmd *cmd),
161 cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
162 struct cycx_x25_cmd *cmd),
163 cycx_x25_irq_connect(struct cycx_device *card,
164 struct cycx_x25_cmd *cmd),
165 cycx_x25_irq_disconnect(struct cycx_device *card,
166 struct cycx_x25_cmd *cmd),
167 cycx_x25_irq_spurious(struct cycx_device *card,
168 struct cycx_x25_cmd *cmd);
169
170/* X.25 firmware interface functions */
171static int cycx_x25_configure(struct cycx_device *card,
172 struct cycx_x25_config *conf),
173 cycx_x25_get_stats(struct cycx_device *card),
174 cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
175 int len, void *buf),
176 cycx_x25_connect_response(struct cycx_device *card,
177 struct cycx_x25_channel *chan),
178 cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
179 u8 lcn);
180
181/* channel functions */
182static int cycx_x25_chan_connect(struct net_device *dev),
183 cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb);
184
185static void cycx_x25_chan_disconnect(struct net_device *dev),
186 cycx_x25_chan_send_event(struct net_device *dev, u8 event);
187
188/* Miscellaneous functions */
189static void cycx_x25_set_chan_state(struct net_device *dev, u8 state),
190 cycx_x25_chan_timer(unsigned long d);
191
192static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble),
193 reset_timer(struct net_device *dev);
194
195static u8 bps_to_speed_code(u32 bps);
196static u8 cycx_log2(u32 n);
197
198static unsigned dec_to_uint(u8 *str, int len);
199
200static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
201 s16 lcn);
202static struct net_device *
203 cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte);
204
205static void cycx_x25_chan_setup(struct net_device *dev);
206
207#ifdef CYCLOMX_X25_DEBUG
208static void hex_dump(char *msg, unsigned char *p, int len);
209static void cycx_x25_dump_config(struct cycx_x25_config *conf);
210static void cycx_x25_dump_stats(struct cycx_x25_stats *stats);
211static void cycx_x25_dump_devs(struct wan_device *wandev);
212#else
213#define hex_dump(msg, p, len)
214#define cycx_x25_dump_config(conf)
215#define cycx_x25_dump_stats(stats)
216#define cycx_x25_dump_devs(wandev)
217#endif
218/* Public Functions */
219
220/* X.25 Protocol Initialization routine.
221 *
222 * This routine is called by the main Cyclom 2X module during setup. At this
223 * point adapter is completely initialized and X.25 firmware is running.
224 * o configure adapter
225 * o initialize protocol-specific fields of the adapter data space.
226 *
227 * Return: 0 o.k.
228 * < 0 failure. */
229int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf)
230{
231 struct cycx_x25_config cfg;
232
233 /* Verify configuration ID */
234 if (conf->config_id != WANCONFIG_X25) {
235 pr_info("%s: invalid configuration ID %u!\n",
236 card->devname, conf->config_id);
237 return -EINVAL;
238 }
239
240 /* Initialize protocol-specific fields */
241 card->mbox = card->hw.dpmbase + X25_MBOX_OFFS;
242 card->u.x.connection_keys = 0;
243 spin_lock_init(&card->u.x.lock);
244
245 /* Configure adapter. Here we set reasonable defaults, then parse
246 * device configuration structure and set configuration options.
247 * Most configuration options are verified and corrected (if
248 * necessary) since we can't rely on the adapter to do so and don't
249 * want it to fail either. */
250 memset(&cfg, 0, sizeof(cfg));
251 cfg.link = 0;
252 cfg.clock = conf->clocking == WANOPT_EXTERNAL ? 8 : 55;
253 cfg.speed = bps_to_speed_code(conf->bps);
254 cfg.n3win = 7;
255 cfg.n2win = 2;
256 cfg.n2 = 5;
257 cfg.nvc = 1;
258 cfg.npvc = 1;
259 cfg.flags = 0x02; /* default = V35 */
260 cfg.t1 = 10; /* line carrier timeout */
261 cfg.t2 = 29; /* tx timeout */
262 cfg.t21 = 180; /* CALL timeout */
263 cfg.t23 = 180; /* CLEAR timeout */
264
265 /* adjust MTU */
266 if (!conf->mtu || conf->mtu >= 512)
267 card->wandev.mtu = 512;
268 else if (conf->mtu >= 256)
269 card->wandev.mtu = 256;
270 else if (conf->mtu >= 128)
271 card->wandev.mtu = 128;
272 else
273 card->wandev.mtu = 64;
274
275 cfg.pktlen = cycx_log2(card->wandev.mtu);
276
277 if (conf->station == WANOPT_DTE) {
278 cfg.locaddr = 3; /* DTE */
279 cfg.remaddr = 1; /* DCE */
280 } else {
281 cfg.locaddr = 1; /* DCE */
282 cfg.remaddr = 3; /* DTE */
283 }
284
285 if (conf->interface == WANOPT_RS232)
286 cfg.flags = 0; /* FIXME just reset the 2nd bit */
287
288 if (conf->u.x25.hi_pvc) {
289 card->u.x.hi_pvc = min_t(unsigned int, conf->u.x25.hi_pvc, 4095);
290 card->u.x.lo_pvc = min_t(unsigned int, conf->u.x25.lo_pvc, card->u.x.hi_pvc);
291 }
292
293 if (conf->u.x25.hi_svc) {
294 card->u.x.hi_svc = min_t(unsigned int, conf->u.x25.hi_svc, 4095);
295 card->u.x.lo_svc = min_t(unsigned int, conf->u.x25.lo_svc, card->u.x.hi_svc);
296 }
297
298 if (card->u.x.lo_pvc == 255)
299 cfg.npvc = 0;
300 else
301 cfg.npvc = card->u.x.hi_pvc - card->u.x.lo_pvc + 1;
302
303 cfg.nvc = card->u.x.hi_svc - card->u.x.lo_svc + 1 + cfg.npvc;
304
305 if (conf->u.x25.hdlc_window)
306 cfg.n2win = min_t(unsigned int, conf->u.x25.hdlc_window, 7);
307
308 if (conf->u.x25.pkt_window)
309 cfg.n3win = min_t(unsigned int, conf->u.x25.pkt_window, 7);
310
311 if (conf->u.x25.t1)
312 cfg.t1 = min_t(unsigned int, conf->u.x25.t1, 30);
313
314 if (conf->u.x25.t2)
315 cfg.t2 = min_t(unsigned int, conf->u.x25.t2, 30);
316
317 if (conf->u.x25.t11_t21)
318 cfg.t21 = min_t(unsigned int, conf->u.x25.t11_t21, 30);
319
320 if (conf->u.x25.t13_t23)
321 cfg.t23 = min_t(unsigned int, conf->u.x25.t13_t23, 30);
322
323 if (conf->u.x25.n2)
324 cfg.n2 = min_t(unsigned int, conf->u.x25.n2, 30);
325
326 /* initialize adapter */
327 if (cycx_x25_configure(card, &cfg))
328 return -EIO;
329
330 /* Initialize protocol-specific fields of adapter data space */
331 card->wandev.bps = conf->bps;
332 card->wandev.interface = conf->interface;
333 card->wandev.clocking = conf->clocking;
334 card->wandev.station = conf->station;
335 card->isr = cycx_x25_irq_handler;
336 card->exec = NULL;
337 card->wandev.update = cycx_wan_update;
338 card->wandev.new_if = cycx_wan_new_if;
339 card->wandev.del_if = cycx_wan_del_if;
340 card->wandev.state = WAN_DISCONNECTED;
341
342 return 0;
343}
344
345/* WAN Device Driver Entry Points */
346/* Update device status & statistics. */
347static int cycx_wan_update(struct wan_device *wandev)
348{
349 /* sanity checks */
350 if (!wandev || !wandev->private)
351 return -EFAULT;
352
353 if (wandev->state == WAN_UNCONFIGURED)
354 return -ENODEV;
355
356 cycx_x25_get_stats(wandev->private);
357
358 return 0;
359}
360
361/* Create new logical channel.
362 * This routine is called by the router when ROUTER_IFNEW IOCTL is being
363 * handled.
364 * o parse media- and hardware-specific configuration
365 * o make sure that a new channel can be created
366 * o allocate resources, if necessary
367 * o prepare network device structure for registration.
368 *
369 * Return: 0 o.k.
370 * < 0 failure (channel will not be created) */
371static int cycx_wan_new_if(struct wan_device *wandev, struct net_device *dev,
372 wanif_conf_t *conf)
373{
374 struct cycx_device *card = wandev->private;
375 struct cycx_x25_channel *chan;
376 int err = 0;
377
378 if (!conf->name[0] || strlen(conf->name) > WAN_IFNAME_SZ) {
379 pr_info("%s: invalid interface name!\n", card->devname);
380 return -EINVAL;
381 }
382
383 dev = alloc_netdev(sizeof(struct cycx_x25_channel), conf->name,
384 cycx_x25_chan_setup);
385 if (!dev)
386 return -ENOMEM;
387
388 chan = netdev_priv(dev);
389 strcpy(chan->name, conf->name);
390 chan->card = card;
391 chan->link = conf->port;
392 chan->protocol = conf->protocol ? ETH_P_X25 : ETH_P_IP;
393 chan->rx_skb = NULL;
394 /* only used in svc connected thru crossover cable */
395 chan->local_addr = NULL;
396
397 if (conf->addr[0] == '@') { /* SVC */
398 int len = strlen(conf->local_addr);
399
400 if (len) {
401 if (len > WAN_ADDRESS_SZ) {
402 pr_err("%s: %s local addr too long!\n",
403 wandev->name, chan->name);
404 err = -EINVAL;
405 goto error;
406 } else {
407 chan->local_addr = kmalloc(len + 1, GFP_KERNEL);
408
409 if (!chan->local_addr) {
410 err = -ENOMEM;
411 goto error;
412 }
413 }
414
415 strncpy(chan->local_addr, conf->local_addr,
416 WAN_ADDRESS_SZ);
417 }
418
419 chan->svc = 1;
420 strncpy(chan->addr, &conf->addr[1], WAN_ADDRESS_SZ);
421 init_timer(&chan->timer);
422 chan->timer.function = cycx_x25_chan_timer;
423 chan->timer.data = (unsigned long)dev;
424
425 /* Set channel timeouts (default if not specified) */
426 chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
427 } else if (isdigit(conf->addr[0])) { /* PVC */
428 s16 lcn = dec_to_uint(conf->addr, 0);
429
430 if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
431 chan->lcn = lcn;
432 else {
433 pr_err("%s: PVC %u is out of range on interface %s!\n",
434 wandev->name, lcn, chan->name);
435 err = -EINVAL;
436 goto error;
437 }
438 } else {
439 pr_err("%s: invalid media address on interface %s!\n",
440 wandev->name, chan->name);
441 err = -EINVAL;
442 goto error;
443 }
444
445 return 0;
446
447error:
448 free_netdev(dev);
449 return err;
450}
451
452/* Delete logical channel. */
453static int cycx_wan_del_if(struct wan_device *wandev, struct net_device *dev)
454{
455 struct cycx_x25_channel *chan = netdev_priv(dev);
456
457 if (chan->svc) {
458 kfree(chan->local_addr);
459 if (chan->state == WAN_CONNECTED)
460 del_timer(&chan->timer);
461 }
462
463 return 0;
464}
465
466
467/* Network Device Interface */
468
469static const struct header_ops cycx_header_ops = {
470 .create = cycx_netdevice_hard_header,
471 .rebuild = cycx_netdevice_rebuild_header,
472};
473
474static const struct net_device_ops cycx_netdev_ops = {
475 .ndo_init = cycx_netdevice_init,
476 .ndo_open = cycx_netdevice_open,
477 .ndo_stop = cycx_netdevice_stop,
478 .ndo_start_xmit = cycx_netdevice_hard_start_xmit,
479 .ndo_get_stats = cycx_netdevice_get_stats,
480};
481
482static void cycx_x25_chan_setup(struct net_device *dev)
483{
484 /* Initialize device driver entry points */
485 dev->netdev_ops = &cycx_netdev_ops;
486 dev->header_ops = &cycx_header_ops;
487
488 /* Initialize media-specific parameters */
489 dev->mtu = CYCX_X25_CHAN_MTU;
490 dev->type = ARPHRD_HWX25; /* ARP h/w type */
491 dev->hard_header_len = 0; /* media header length */
492 dev->addr_len = 0; /* hardware address length */
493}
494
495/* Initialize Linux network interface.
496 *
497 * This routine is called only once for each interface, during Linux network
498 * interface registration. Returning anything but zero will fail interface
499 * registration. */
500static int cycx_netdevice_init(struct net_device *dev)
501{
502 struct cycx_x25_channel *chan = netdev_priv(dev);
503 struct cycx_device *card = chan->card;
504 struct wan_device *wandev = &card->wandev;
505
506 if (!chan->svc)
507 *(__be16*)dev->dev_addr = htons(chan->lcn);
508
509 /* Initialize hardware parameters (just for reference) */
510 dev->irq = wandev->irq;
511 dev->dma = wandev->dma;
512 dev->base_addr = wandev->ioport;
513 dev->mem_start = (unsigned long)wandev->maddr;
514 dev->mem_end = (unsigned long)(wandev->maddr +
515 wandev->msize - 1);
516 dev->flags |= IFF_NOARP;
517
518 /* Set transmit buffer queue length */
519 dev->tx_queue_len = 10;
520
521 /* Initialize socket buffers */
522 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
523
524 return 0;
525}
526
527/* Open network interface.
528 * o prevent module from unloading by incrementing use count
529 * o if link is disconnected then initiate connection
530 *
531 * Return 0 if O.k. or errno. */
532static int cycx_netdevice_open(struct net_device *dev)
533{
534 if (netif_running(dev))
535 return -EBUSY; /* only one open is allowed */
536
537 netif_start_queue(dev);
538 return 0;
539}
540
541/* Close network interface.
542 * o reset flags.
543 * o if there's no more open channels then disconnect physical link. */
544static int cycx_netdevice_stop(struct net_device *dev)
545{
546 struct cycx_x25_channel *chan = netdev_priv(dev);
547
548 netif_stop_queue(dev);
549
550 if (chan->state == WAN_CONNECTED || chan->state == WAN_CONNECTING)
551 cycx_x25_chan_disconnect(dev);
552
553 return 0;
554}
555
556/* Build media header.
557 * o encapsulate packet according to encapsulation type.
558 *
559 * The trick here is to put packet type (Ethertype) into 'protocol' field of
560 * the socket buffer, so that we don't forget it. If encapsulation fails,
561 * set skb->protocol to 0 and discard packet later.
562 *
563 * Return: media header length. */
564static int cycx_netdevice_hard_header(struct sk_buff *skb,
565 struct net_device *dev, u16 type,
566 const void *daddr, const void *saddr,
567 unsigned len)
568{
569 skb->protocol = htons(type);
570
571 return dev->hard_header_len;
572}
573
574/* * Re-build media header.
575 * Return: 1 physical address resolved.
576 * 0 physical address not resolved */
577static int cycx_netdevice_rebuild_header(struct sk_buff *skb)
578{
579 return 1;
580}
581
582/* Send a packet on a network interface.
583 * o set busy flag (marks start of the transmission).
584 * o check link state. If link is not up, then drop the packet.
585 * o check channel status. If it's down then initiate a call.
586 * o pass a packet to corresponding WAN device.
587 * o free socket buffer
588 *
589 * Return: 0 complete (socket buffer must be freed)
590 * non-0 packet may be re-transmitted (tbusy must be set)
591 *
592 * Notes:
593 * 1. This routine is called either by the protocol stack or by the "net
594 * bottom half" (with interrupts enabled).
595 * 2. Setting tbusy flag will inhibit further transmit requests from the
596 * protocol stack and can be used for flow control with protocol layer. */
597static netdev_tx_t cycx_netdevice_hard_start_xmit(struct sk_buff *skb,
598 struct net_device *dev)
599{
600 struct cycx_x25_channel *chan = netdev_priv(dev);
601 struct cycx_device *card = chan->card;
602
603 if (!chan->svc)
604 chan->protocol = ntohs(skb->protocol);
605
606 if (card->wandev.state != WAN_CONNECTED)
607 ++chan->ifstats.tx_dropped;
608 else if (chan->svc && chan->protocol &&
609 chan->protocol != ntohs(skb->protocol)) {
610 pr_info("%s: unsupported Ethertype 0x%04X on interface %s!\n",
611 card->devname, ntohs(skb->protocol), dev->name);
612 ++chan->ifstats.tx_errors;
613 } else if (chan->protocol == ETH_P_IP) {
614 switch (chan->state) {
615 case WAN_DISCONNECTED:
616 if (cycx_x25_chan_connect(dev)) {
617 netif_stop_queue(dev);
618 return NETDEV_TX_BUSY;
619 }
620 /* fall thru */
621 case WAN_CONNECTED:
622 reset_timer(dev);
623 dev->trans_start = jiffies;
624 netif_stop_queue(dev);
625
626 if (cycx_x25_chan_send(dev, skb))
627 return NETDEV_TX_BUSY;
628
629 break;
630 default:
631 ++chan->ifstats.tx_dropped;
632 ++card->wandev.stats.tx_dropped;
633 }
634 } else { /* chan->protocol == ETH_P_X25 */
635 switch (skb->data[0]) {
636 case X25_IFACE_DATA:
637 break;
638 case X25_IFACE_CONNECT:
639 cycx_x25_chan_connect(dev);
640 goto free_packet;
641 case X25_IFACE_DISCONNECT:
642 cycx_x25_chan_disconnect(dev);
643 goto free_packet;
644 default:
645 pr_info("%s: unknown %d x25-iface request on %s!\n",
646 card->devname, skb->data[0], dev->name);
647 ++chan->ifstats.tx_errors;
648 goto free_packet;
649 }
650
651 skb_pull(skb, 1); /* Remove control byte */
652 reset_timer(dev);
653 dev->trans_start = jiffies;
654 netif_stop_queue(dev);
655
656 if (cycx_x25_chan_send(dev, skb)) {
657 /* prepare for future retransmissions */
658 skb_push(skb, 1);
659 return NETDEV_TX_BUSY;
660 }
661 }
662
663free_packet:
664 dev_kfree_skb(skb);
665
666 return NETDEV_TX_OK;
667}
668
669/* Get Ethernet-style interface statistics.
670 * Return a pointer to struct net_device_stats */
671static struct net_device_stats *cycx_netdevice_get_stats(struct net_device *dev)
672{
673 struct cycx_x25_channel *chan = netdev_priv(dev);
674
675 return chan ? &chan->ifstats : NULL;
676}
677
678/* Interrupt Handlers */
679/* X.25 Interrupt Service Routine. */
680static void cycx_x25_irq_handler(struct cycx_device *card)
681{
682 struct cycx_x25_cmd cmd;
683 u16 z = 0;
684
685 card->in_isr = 1;
686 card->buff_int_mode_unbusy = 0;
687 cycx_peek(&card->hw, X25_RXMBOX_OFFS, &cmd, sizeof(cmd));
688
689 switch (cmd.command) {
690 case X25_DATA_INDICATION:
691 cycx_x25_irq_rx(card, &cmd);
692 break;
693 case X25_ACK_FROM_VC:
694 cycx_x25_irq_tx(card, &cmd);
695 break;
696 case X25_LOG:
697 cycx_x25_irq_log(card, &cmd);
698 break;
699 case X25_STATISTIC:
700 cycx_x25_irq_stat(card, &cmd);
701 break;
702 case X25_CONNECT_CONFIRM:
703 cycx_x25_irq_connect_confirm(card, &cmd);
704 break;
705 case X25_CONNECT_INDICATION:
706 cycx_x25_irq_connect(card, &cmd);
707 break;
708 case X25_DISCONNECT_INDICATION:
709 cycx_x25_irq_disconnect(card, &cmd);
710 break;
711 case X25_DISCONNECT_CONFIRM:
712 cycx_x25_irq_disconnect_confirm(card, &cmd);
713 break;
714 case X25_LINE_ON:
715 cycx_set_state(card, WAN_CONNECTED);
716 break;
717 case X25_LINE_OFF:
718 cycx_set_state(card, WAN_DISCONNECTED);
719 break;
720 default:
721 cycx_x25_irq_spurious(card, &cmd);
722 break;
723 }
724
725 cycx_poke(&card->hw, 0, &z, sizeof(z));
726 cycx_poke(&card->hw, X25_RXMBOX_OFFS, &z, sizeof(z));
727 card->in_isr = 0;
728}
729
730/* Transmit interrupt handler.
731 * o Release socket buffer
732 * o Clear 'tbusy' flag */
733static void cycx_x25_irq_tx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
734{
735 struct net_device *dev;
736 struct wan_device *wandev = &card->wandev;
737 u8 lcn;
738
739 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
740
741 /* unbusy device and then dev_tint(); */
742 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
743 if (dev) {
744 card->buff_int_mode_unbusy = 1;
745 netif_wake_queue(dev);
746 } else
747 pr_err("%s:ackvc for inexistent lcn %d\n", card->devname, lcn);
748}
749
750/* Receive interrupt handler.
751 * This routine handles fragmented IP packets using M-bit according to the
752 * RFC1356.
753 * o map logical channel number to network interface.
754 * o allocate socket buffer or append received packet to the existing one.
755 * o if M-bit is reset (i.e. it's the last packet in a sequence) then
756 * decapsulate packet and pass socket buffer to the protocol stack.
757 *
758 * Notes:
759 * 1. When allocating a socket buffer, if M-bit is set then more data is
760 * coming and we have to allocate buffer for the maximum IP packet size
761 * expected on this channel.
762 * 2. If something goes wrong and X.25 packet has to be dropped (e.g. no
763 * socket buffers available) the whole packet sequence must be discarded. */
764static void cycx_x25_irq_rx(struct cycx_device *card, struct cycx_x25_cmd *cmd)
765{
766 struct wan_device *wandev = &card->wandev;
767 struct net_device *dev;
768 struct cycx_x25_channel *chan;
769 struct sk_buff *skb;
770 u8 bitm, lcn;
771 int pktlen = cmd->len - 5;
772
773 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
774 cycx_peek(&card->hw, cmd->buf + 4, &bitm, sizeof(bitm));
775 bitm &= 0x10;
776
777 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
778 if (!dev) {
779 /* Invalid channel, discard packet */
780 pr_info("%s: receiving on orphaned LCN %d!\n",
781 card->devname, lcn);
782 return;
783 }
784
785 chan = netdev_priv(dev);
786 reset_timer(dev);
787
788 if (chan->drop_sequence) {
789 if (!bitm)
790 chan->drop_sequence = 0;
791 else
792 return;
793 }
794
795 if ((skb = chan->rx_skb) == NULL) {
796 /* Allocate new socket buffer */
797 int bufsize = bitm ? dev->mtu : pktlen;
798
799 if ((skb = dev_alloc_skb((chan->protocol == ETH_P_X25 ? 1 : 0) +
800 bufsize +
801 dev->hard_header_len)) == NULL) {
802 pr_info("%s: no socket buffers available!\n",
803 card->devname);
804 chan->drop_sequence = 1;
805 ++chan->ifstats.rx_dropped;
806 return;
807 }
808
809 if (chan->protocol == ETH_P_X25) /* X.25 socket layer control */
810 /* 0 = data packet (dev_alloc_skb zeroed skb->data) */
811 skb_put(skb, 1);
812
813 skb->dev = dev;
814 skb->protocol = htons(chan->protocol);
815 chan->rx_skb = skb;
816 }
817
818 if (skb_tailroom(skb) < pktlen) {
819 /* No room for the packet. Call off the whole thing! */
820 dev_kfree_skb_irq(skb);
821 chan->rx_skb = NULL;
822
823 if (bitm)
824 chan->drop_sequence = 1;
825
826 pr_info("%s: unexpectedly long packet sequence on interface %s!\n",
827 card->devname, dev->name);
828 ++chan->ifstats.rx_length_errors;
829 return;
830 }
831
832 /* Append packet to the socket buffer */
833 cycx_peek(&card->hw, cmd->buf + 5, skb_put(skb, pktlen), pktlen);
834
835 if (bitm)
836 return; /* more data is coming */
837
838 chan->rx_skb = NULL; /* dequeue packet */
839
840 ++chan->ifstats.rx_packets;
841 chan->ifstats.rx_bytes += pktlen;
842
843 skb_reset_mac_header(skb);
844 netif_rx(skb);
845}
846
847/* Connect interrupt handler. */
848static void cycx_x25_irq_connect(struct cycx_device *card,
849 struct cycx_x25_cmd *cmd)
850{
851 struct wan_device *wandev = &card->wandev;
852 struct net_device *dev = NULL;
853 struct cycx_x25_channel *chan;
854 u8 d[32],
855 loc[24],
856 rem[24];
857 u8 lcn, sizeloc, sizerem;
858
859 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
860 cycx_peek(&card->hw, cmd->buf + 5, &sizeloc, sizeof(sizeloc));
861 cycx_peek(&card->hw, cmd->buf + 6, d, cmd->len - 6);
862
863 sizerem = sizeloc >> 4;
864 sizeloc &= 0x0F;
865
866 loc[0] = rem[0] = '\0';
867
868 if (sizeloc)
869 nibble_to_byte(d, loc, sizeloc, 0);
870
871 if (sizerem)
872 nibble_to_byte(d + (sizeloc >> 1), rem, sizerem, sizeloc & 1);
873
874 dprintk(1, KERN_INFO "%s:lcn=%d, local=%s, remote=%s\n",
875 __func__, lcn, loc, rem);
876
877 dev = cycx_x25_get_dev_by_dte_addr(wandev, rem);
878 if (!dev) {
879 /* Invalid channel, discard packet */
880 pr_info("%s: connect not expected: remote %s!\n",
881 card->devname, rem);
882 return;
883 }
884
885 chan = netdev_priv(dev);
886 chan->lcn = lcn;
887 cycx_x25_connect_response(card, chan);
888 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
889}
890
891/* Connect confirm interrupt handler. */
892static void cycx_x25_irq_connect_confirm(struct cycx_device *card,
893 struct cycx_x25_cmd *cmd)
894{
895 struct wan_device *wandev = &card->wandev;
896 struct net_device *dev;
897 struct cycx_x25_channel *chan;
898 u8 lcn, key;
899
900 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
901 cycx_peek(&card->hw, cmd->buf + 1, &key, sizeof(key));
902 dprintk(1, KERN_INFO "%s: %s:lcn=%d, key=%d\n",
903 card->devname, __func__, lcn, key);
904
905 dev = cycx_x25_get_dev_by_lcn(wandev, -key);
906 if (!dev) {
907 /* Invalid channel, discard packet */
908 clear_bit(--key, (void*)&card->u.x.connection_keys);
909 pr_info("%s: connect confirm not expected: lcn %d, key=%d!\n",
910 card->devname, lcn, key);
911 return;
912 }
913
914 clear_bit(--key, (void*)&card->u.x.connection_keys);
915 chan = netdev_priv(dev);
916 chan->lcn = lcn;
917 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
918}
919
920/* Disconnect confirm interrupt handler. */
921static void cycx_x25_irq_disconnect_confirm(struct cycx_device *card,
922 struct cycx_x25_cmd *cmd)
923{
924 struct wan_device *wandev = &card->wandev;
925 struct net_device *dev;
926 u8 lcn;
927
928 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
929 dprintk(1, KERN_INFO "%s: %s:lcn=%d\n",
930 card->devname, __func__, lcn);
931 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
932 if (!dev) {
933 /* Invalid channel, discard packet */
934 pr_info("%s:disconnect confirm not expected!:lcn %d\n",
935 card->devname, lcn);
936 return;
937 }
938
939 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
940}
941
942/* disconnect interrupt handler. */
943static void cycx_x25_irq_disconnect(struct cycx_device *card,
944 struct cycx_x25_cmd *cmd)
945{
946 struct wan_device *wandev = &card->wandev;
947 struct net_device *dev;
948 u8 lcn;
949
950 cycx_peek(&card->hw, cmd->buf, &lcn, sizeof(lcn));
951 dprintk(1, KERN_INFO "%s:lcn=%d\n", __func__, lcn);
952
953 dev = cycx_x25_get_dev_by_lcn(wandev, lcn);
954 if (dev) {
955 struct cycx_x25_channel *chan = netdev_priv(dev);
956
957 cycx_x25_disconnect_response(card, chan->link, lcn);
958 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
959 } else
960 cycx_x25_disconnect_response(card, 0, lcn);
961}
962
963/* LOG interrupt handler. */
964static void cycx_x25_irq_log(struct cycx_device *card, struct cycx_x25_cmd *cmd)
965{
966#if CYCLOMX_X25_DEBUG
967 char bf[20];
968 u16 size, toread, link, msg_code;
969 u8 code, routine;
970
971 cycx_peek(&card->hw, cmd->buf, &msg_code, sizeof(msg_code));
972 cycx_peek(&card->hw, cmd->buf + 2, &link, sizeof(link));
973 cycx_peek(&card->hw, cmd->buf + 4, &size, sizeof(size));
974 /* at most 20 bytes are available... thanks to Daniela :) */
975 toread = size < 20 ? size : 20;
976 cycx_peek(&card->hw, cmd->buf + 10, &bf, toread);
977 cycx_peek(&card->hw, cmd->buf + 10 + toread, &code, 1);
978 cycx_peek(&card->hw, cmd->buf + 10 + toread + 1, &routine, 1);
979
980 pr_info("cycx_x25_irq_handler: X25_LOG (0x4500) indic.:\n");
981 pr_info("cmd->buf=0x%X\n", cmd->buf);
982 pr_info("Log message code=0x%X\n", msg_code);
983 pr_info("Link=%d\n", link);
984 pr_info("log code=0x%X\n", code);
985 pr_info("log routine=0x%X\n", routine);
986 pr_info("Message size=%d\n", size);
987 hex_dump("Message", bf, toread);
988#endif
989}
990
991/* STATISTIC interrupt handler. */
992static void cycx_x25_irq_stat(struct cycx_device *card,
993 struct cycx_x25_cmd *cmd)
994{
995 cycx_peek(&card->hw, cmd->buf, &card->u.x.stats,
996 sizeof(card->u.x.stats));
997 hex_dump("cycx_x25_irq_stat", (unsigned char*)&card->u.x.stats,
998 sizeof(card->u.x.stats));
999 cycx_x25_dump_stats(&card->u.x.stats);
1000 wake_up_interruptible(&card->wait_stats);
1001}
1002
1003/* Spurious interrupt handler.
1004 * o print a warning
1005 * If number of spurious interrupts exceeded some limit, then ??? */
1006static void cycx_x25_irq_spurious(struct cycx_device *card,
1007 struct cycx_x25_cmd *cmd)
1008{
1009 pr_info("%s: spurious interrupt (0x%X)!\n",
1010 card->devname, cmd->command);
1011}
1012#ifdef CYCLOMX_X25_DEBUG
1013static void hex_dump(char *msg, unsigned char *p, int len)
1014{
1015 print_hex_dump(KERN_INFO, msg, DUMP_PREFIX_OFFSET, 16, 1,
1016 p, len, true);
1017}
1018#endif
1019
1020/* Cyclom 2X Firmware-Specific Functions */
1021/* Exec X.25 command. */
1022static int x25_exec(struct cycx_device *card, int command, int link,
1023 void *d1, int len1, void *d2, int len2)
1024{
1025 struct cycx_x25_cmd c;
1026 unsigned long flags;
1027 u32 addr = 0x1200 + 0x2E0 * link + 0x1E2;
1028 u8 retry = CYCX_X25_MAX_CMD_RETRY;
1029 int err = 0;
1030
1031 c.command = command;
1032 c.link = link;
1033 c.len = len1 + len2;
1034
1035 spin_lock_irqsave(&card->u.x.lock, flags);
1036
1037 /* write command */
1038 cycx_poke(&card->hw, X25_MBOX_OFFS, &c, sizeof(c) - sizeof(c.buf));
1039
1040 /* write X.25 data */
1041 if (d1) {
1042 cycx_poke(&card->hw, addr, d1, len1);
1043
1044 if (d2) {
1045 if (len2 > 254) {
1046 u32 addr1 = 0xA00 + 0x400 * link;
1047
1048 cycx_poke(&card->hw, addr + len1, d2, 249);
1049 cycx_poke(&card->hw, addr1, ((u8*)d2) + 249,
1050 len2 - 249);
1051 } else
1052 cycx_poke(&card->hw, addr + len1, d2, len2);
1053 }
1054 }
1055
1056 /* generate interruption, executing command */
1057 cycx_intr(&card->hw);
1058
1059 /* wait till card->mbox == 0 */
1060 do {
1061 err = cycx_exec(card->mbox);
1062 } while (retry-- && err);
1063
1064 spin_unlock_irqrestore(&card->u.x.lock, flags);
1065
1066 return err;
1067}
1068
1069/* Configure adapter. */
1070static int cycx_x25_configure(struct cycx_device *card,
1071 struct cycx_x25_config *conf)
1072{
1073 struct {
1074 u16 nlinks;
1075 struct cycx_x25_config conf[2];
1076 } x25_cmd_conf;
1077
1078 memset(&x25_cmd_conf, 0, sizeof(x25_cmd_conf));
1079 x25_cmd_conf.nlinks = 2;
1080 x25_cmd_conf.conf[0] = *conf;
1081 /* FIXME: we need to find a way in the wanrouter framework
1082 to configure the second link, for now lets use it
1083 with the same config from the first link, fixing
1084 the interface type to RS232, the speed in 38400 and
1085 the clock to external */
1086 x25_cmd_conf.conf[1] = *conf;
1087 x25_cmd_conf.conf[1].link = 1;
1088 x25_cmd_conf.conf[1].speed = 5; /* 38400 */
1089 x25_cmd_conf.conf[1].clock = 8;
1090 x25_cmd_conf.conf[1].flags = 0; /* default = RS232 */
1091
1092 cycx_x25_dump_config(&x25_cmd_conf.conf[0]);
1093 cycx_x25_dump_config(&x25_cmd_conf.conf[1]);
1094
1095 return x25_exec(card, X25_CONFIG, 0,
1096 &x25_cmd_conf, sizeof(x25_cmd_conf), NULL, 0);
1097}
1098
1099/* Get protocol statistics. */
1100static int cycx_x25_get_stats(struct cycx_device *card)
1101{
1102 /* the firmware expects 20 in the size field!!!
1103 thanks to Daniela */
1104 int err = x25_exec(card, X25_STATISTIC, 0, NULL, 20, NULL, 0);
1105
1106 if (err)
1107 return err;
1108
1109 interruptible_sleep_on(&card->wait_stats);
1110
1111 if (signal_pending(current))
1112 return -EINTR;
1113
1114 card->wandev.stats.rx_packets = card->u.x.stats.n2_rx_frames;
1115 card->wandev.stats.rx_over_errors = card->u.x.stats.rx_over_errors;
1116 card->wandev.stats.rx_crc_errors = card->u.x.stats.rx_crc_errors;
1117 card->wandev.stats.rx_length_errors = 0; /* not available from fw */
1118 card->wandev.stats.rx_frame_errors = 0; /* not available from fw */
1119 card->wandev.stats.rx_missed_errors = card->u.x.stats.rx_aborts;
1120 card->wandev.stats.rx_dropped = 0; /* not available from fw */
1121 card->wandev.stats.rx_errors = 0; /* not available from fw */
1122 card->wandev.stats.tx_packets = card->u.x.stats.n2_tx_frames;
1123 card->wandev.stats.tx_aborted_errors = card->u.x.stats.tx_aborts;
1124 card->wandev.stats.tx_dropped = 0; /* not available from fw */
1125 card->wandev.stats.collisions = 0; /* not available from fw */
1126 card->wandev.stats.tx_errors = 0; /* not available from fw */
1127
1128 cycx_x25_dump_devs(&card->wandev);
1129
1130 return 0;
1131}
1132
1133/* return the number of nibbles */
1134static int byte_to_nibble(u8 *s, u8 *d, char *nibble)
1135{
1136 int i = 0;
1137
1138 if (*nibble && *s) {
1139 d[i] |= *s++ - '0';
1140 *nibble = 0;
1141 ++i;
1142 }
1143
1144 while (*s) {
1145 d[i] = (*s - '0') << 4;
1146 if (*(s + 1))
1147 d[i] |= *(s + 1) - '0';
1148 else {
1149 *nibble = 1;
1150 break;
1151 }
1152 ++i;
1153 s += 2;
1154 }
1155
1156 return i;
1157}
1158
1159static void nibble_to_byte(u8 *s, u8 *d, u8 len, u8 nibble)
1160{
1161 if (nibble) {
1162 *d++ = '0' + (*s++ & 0x0F);
1163 --len;
1164 }
1165
1166 while (len) {
1167 *d++ = '0' + (*s >> 4);
1168
1169 if (--len) {
1170 *d++ = '0' + (*s & 0x0F);
1171 --len;
1172 } else break;
1173
1174 ++s;
1175 }
1176
1177 *d = '\0';
1178}
1179
1180/* Place X.25 call. */
1181static int x25_place_call(struct cycx_device *card,
1182 struct cycx_x25_channel *chan)
1183{
1184 int err = 0,
1185 len;
1186 char d[64],
1187 nibble = 0,
1188 mylen = chan->local_addr ? strlen(chan->local_addr) : 0,
1189 remotelen = strlen(chan->addr);
1190 u8 key;
1191
1192 if (card->u.x.connection_keys == ~0U) {
1193 pr_info("%s: too many simultaneous connection requests!\n",
1194 card->devname);
1195 return -EAGAIN;
1196 }
1197
1198 key = ffz(card->u.x.connection_keys);
1199 set_bit(key, (void*)&card->u.x.connection_keys);
1200 ++key;
1201 dprintk(1, KERN_INFO "%s:x25_place_call:key=%d\n", card->devname, key);
1202 memset(d, 0, sizeof(d));
1203 d[1] = key; /* user key */
1204 d[2] = 0x10;
1205 d[4] = 0x0B;
1206
1207 len = byte_to_nibble(chan->addr, d + 6, &nibble);
1208
1209 if (chan->local_addr)
1210 len += byte_to_nibble(chan->local_addr, d + 6 + len, &nibble);
1211
1212 if (nibble)
1213 ++len;
1214
1215 d[5] = mylen << 4 | remotelen;
1216 d[6 + len + 1] = 0xCC; /* TCP/IP over X.25, thanks to Daniela :) */
1217
1218 if ((err = x25_exec(card, X25_CONNECT_REQUEST, chan->link,
1219 &d, 7 + len + 1, NULL, 0)) != 0)
1220 clear_bit(--key, (void*)&card->u.x.connection_keys);
1221 else
1222 chan->lcn = -key;
1223
1224 return err;
1225}
1226
1227/* Place X.25 CONNECT RESPONSE. */
1228static int cycx_x25_connect_response(struct cycx_device *card,
1229 struct cycx_x25_channel *chan)
1230{
1231 u8 d[8];
1232
1233 memset(d, 0, sizeof(d));
1234 d[0] = d[3] = chan->lcn;
1235 d[2] = 0x10;
1236 d[4] = 0x0F;
1237 d[7] = 0xCC; /* TCP/IP over X.25, thanks Daniela */
1238
1239 return x25_exec(card, X25_CONNECT_RESPONSE, chan->link, &d, 8, NULL, 0);
1240}
1241
1242/* Place X.25 DISCONNECT RESPONSE. */
1243static int cycx_x25_disconnect_response(struct cycx_device *card, u8 link,
1244 u8 lcn)
1245{
1246 char d[5];
1247
1248 memset(d, 0, sizeof(d));
1249 d[0] = d[3] = lcn;
1250 d[2] = 0x10;
1251 d[4] = 0x17;
1252
1253 return x25_exec(card, X25_DISCONNECT_RESPONSE, link, &d, 5, NULL, 0);
1254}
1255
1256/* Clear X.25 call. */
1257static int x25_clear_call(struct cycx_device *card, u8 link, u8 lcn, u8 cause,
1258 u8 diagn)
1259{
1260 u8 d[7];
1261
1262 memset(d, 0, sizeof(d));
1263 d[0] = d[3] = lcn;
1264 d[2] = 0x10;
1265 d[4] = 0x13;
1266 d[5] = cause;
1267 d[6] = diagn;
1268
1269 return x25_exec(card, X25_DISCONNECT_REQUEST, link, d, 7, NULL, 0);
1270}
1271
1272/* Send X.25 data packet. */
1273static int cycx_x25_send(struct cycx_device *card, u8 link, u8 lcn, u8 bitm,
1274 int len, void *buf)
1275{
1276 u8 d[] = "?\xFF\x10??";
1277
1278 d[0] = d[3] = lcn;
1279 d[4] = bitm;
1280
1281 return x25_exec(card, X25_DATA_REQUEST, link, &d, 5, buf, len);
1282}
1283
1284/* Miscellaneous */
1285/* Find network device by its channel number. */
1286static struct net_device *cycx_x25_get_dev_by_lcn(struct wan_device *wandev,
1287 s16 lcn)
1288{
1289 struct net_device *dev = wandev->dev;
1290 struct cycx_x25_channel *chan;
1291
1292 while (dev) {
1293 chan = netdev_priv(dev);
1294
1295 if (chan->lcn == lcn)
1296 break;
1297 dev = chan->slave;
1298 }
1299 return dev;
1300}
1301
1302/* Find network device by its remote dte address. */
1303static struct net_device *
1304 cycx_x25_get_dev_by_dte_addr(struct wan_device *wandev, char *dte)
1305{
1306 struct net_device *dev = wandev->dev;
1307 struct cycx_x25_channel *chan;
1308
1309 while (dev) {
1310 chan = netdev_priv(dev);
1311
1312 if (!strcmp(chan->addr, dte))
1313 break;
1314 dev = chan->slave;
1315 }
1316 return dev;
1317}
1318
1319/* Initiate connection on the logical channel.
1320 * o for PVC we just get channel configuration
1321 * o for SVCs place an X.25 call
1322 *
1323 * Return: 0 connected
1324 * >0 connection in progress
1325 * <0 failure */
1326static int cycx_x25_chan_connect(struct net_device *dev)
1327{
1328 struct cycx_x25_channel *chan = netdev_priv(dev);
1329 struct cycx_device *card = chan->card;
1330
1331 if (chan->svc) {
1332 if (!chan->addr[0])
1333 return -EINVAL; /* no destination address */
1334
1335 dprintk(1, KERN_INFO "%s: placing X.25 call to %s...\n",
1336 card->devname, chan->addr);
1337
1338 if (x25_place_call(card, chan))
1339 return -EIO;
1340
1341 cycx_x25_set_chan_state(dev, WAN_CONNECTING);
1342 return 1;
1343 } else
1344 cycx_x25_set_chan_state(dev, WAN_CONNECTED);
1345
1346 return 0;
1347}
1348
1349/* Disconnect logical channel.
1350 * o if SVC then clear X.25 call */
1351static void cycx_x25_chan_disconnect(struct net_device *dev)
1352{
1353 struct cycx_x25_channel *chan = netdev_priv(dev);
1354
1355 if (chan->svc) {
1356 x25_clear_call(chan->card, chan->link, chan->lcn, 0, 0);
1357 cycx_x25_set_chan_state(dev, WAN_DISCONNECTING);
1358 } else
1359 cycx_x25_set_chan_state(dev, WAN_DISCONNECTED);
1360}
1361
1362/* Called by kernel timer */
1363static void cycx_x25_chan_timer(unsigned long d)
1364{
1365 struct net_device *dev = (struct net_device *)d;
1366 struct cycx_x25_channel *chan = netdev_priv(dev);
1367
1368 if (chan->state == WAN_CONNECTED)
1369 cycx_x25_chan_disconnect(dev);
1370 else
1371 pr_err("%s: %s for svc (%s) not connected!\n",
1372 chan->card->devname, __func__, dev->name);
1373}
1374
1375/* Set logical channel state. */
1376static void cycx_x25_set_chan_state(struct net_device *dev, u8 state)
1377{
1378 struct cycx_x25_channel *chan = netdev_priv(dev);
1379 struct cycx_device *card = chan->card;
1380 unsigned long flags;
1381 char *string_state = NULL;
1382
1383 spin_lock_irqsave(&card->lock, flags);
1384
1385 if (chan->state != state) {
1386 if (chan->svc && chan->state == WAN_CONNECTED)
1387 del_timer(&chan->timer);
1388
1389 switch (state) {
1390 case WAN_CONNECTED:
1391 string_state = "connected!";
1392 *(__be16*)dev->dev_addr = htons(chan->lcn);
1393 netif_wake_queue(dev);
1394 reset_timer(dev);
1395
1396 if (chan->protocol == ETH_P_X25)
1397 cycx_x25_chan_send_event(dev,
1398 X25_IFACE_CONNECT);
1399
1400 break;
1401 case WAN_CONNECTING:
1402 string_state = "connecting...";
1403 break;
1404 case WAN_DISCONNECTING:
1405 string_state = "disconnecting...";
1406 break;
1407 case WAN_DISCONNECTED:
1408 string_state = "disconnected!";
1409
1410 if (chan->svc) {
1411 *(unsigned short*)dev->dev_addr = 0;
1412 chan->lcn = 0;
1413 }
1414
1415 if (chan->protocol == ETH_P_X25)
1416 cycx_x25_chan_send_event(dev,
1417 X25_IFACE_DISCONNECT);
1418
1419 netif_wake_queue(dev);
1420 break;
1421 }
1422
1423 pr_info("%s: interface %s %s\n",
1424 card->devname, dev->name, string_state);
1425 chan->state = state;
1426 }
1427
1428 spin_unlock_irqrestore(&card->lock, flags);
1429}
1430
1431/* Send packet on a logical channel.
1432 * When this function is called, tx_skb field of the channel data space
1433 * points to the transmit socket buffer. When transmission is complete,
1434 * release socket buffer and reset 'tbusy' flag.
1435 *
1436 * Return: 0 - transmission complete
1437 * 1 - busy
1438 *
1439 * Notes:
1440 * 1. If packet length is greater than MTU for this channel, we'll fragment
1441 * the packet into 'complete sequence' using M-bit.
1442 * 2. When transmission is complete, an event notification should be issued
1443 * to the router. */
1444static int cycx_x25_chan_send(struct net_device *dev, struct sk_buff *skb)
1445{
1446 struct cycx_x25_channel *chan = netdev_priv(dev);
1447 struct cycx_device *card = chan->card;
1448 int bitm = 0; /* final packet */
1449 unsigned len = skb->len;
1450
1451 if (skb->len > card->wandev.mtu) {
1452 len = card->wandev.mtu;
1453 bitm = 0x10; /* set M-bit (more data) */
1454 }
1455
1456 if (cycx_x25_send(card, chan->link, chan->lcn, bitm, len, skb->data))
1457 return 1;
1458
1459 if (bitm) {
1460 skb_pull(skb, len);
1461 return 1;
1462 }
1463
1464 ++chan->ifstats.tx_packets;
1465 chan->ifstats.tx_bytes += len;
1466
1467 return 0;
1468}
1469
1470/* Send event (connection, disconnection, etc) to X.25 socket layer */
1471
1472static void cycx_x25_chan_send_event(struct net_device *dev, u8 event)
1473{
1474 struct sk_buff *skb;
1475 unsigned char *ptr;
1476
1477 if ((skb = dev_alloc_skb(1)) == NULL) {
1478 pr_err("%s: out of memory\n", __func__);
1479 return;
1480 }
1481
1482 ptr = skb_put(skb, 1);
1483 *ptr = event;
1484
1485 skb->protocol = x25_type_trans(skb, dev);
1486 netif_rx(skb);
1487}
1488
1489/* Convert line speed in bps to a number used by cyclom 2x code. */
1490static u8 bps_to_speed_code(u32 bps)
1491{
1492 u8 number = 0; /* defaults to the lowest (1200) speed ;> */
1493
1494 if (bps >= 512000) number = 8;
1495 else if (bps >= 256000) number = 7;
1496 else if (bps >= 64000) number = 6;
1497 else if (bps >= 38400) number = 5;
1498 else if (bps >= 19200) number = 4;
1499 else if (bps >= 9600) number = 3;
1500 else if (bps >= 4800) number = 2;
1501 else if (bps >= 2400) number = 1;
1502
1503 return number;
1504}
1505
1506/* log base 2 */
1507static u8 cycx_log2(u32 n)
1508{
1509 u8 log = 0;
1510
1511 if (!n)
1512 return 0;
1513
1514 while (n > 1) {
1515 n >>= 1;
1516 ++log;
1517 }
1518
1519 return log;
1520}
1521
1522/* Convert decimal string to unsigned integer.
1523 * If len != 0 then only 'len' characters of the string are converted. */
1524static unsigned dec_to_uint(u8 *str, int len)
1525{
1526 unsigned val = 0;
1527
1528 if (!len)
1529 len = strlen(str);
1530
1531 for (; len && isdigit(*str); ++str, --len)
1532 val = (val * 10) + (*str - (unsigned) '0');
1533
1534 return val;
1535}
1536
1537static void reset_timer(struct net_device *dev)
1538{
1539 struct cycx_x25_channel *chan = netdev_priv(dev);
1540
1541 if (chan->svc)
1542 mod_timer(&chan->timer, jiffies+chan->idle_tmout*HZ);
1543}
1544#ifdef CYCLOMX_X25_DEBUG
1545static void cycx_x25_dump_config(struct cycx_x25_config *conf)
1546{
1547 pr_info("X.25 configuration\n");
1548 pr_info("-----------------\n");
1549 pr_info("link number=%d\n", conf->link);
1550 pr_info("line speed=%d\n", conf->speed);
1551 pr_info("clock=%sternal\n", conf->clock == 8 ? "Ex" : "In");
1552 pr_info("# level 2 retransm.=%d\n", conf->n2);
1553 pr_info("level 2 window=%d\n", conf->n2win);
1554 pr_info("level 3 window=%d\n", conf->n3win);
1555 pr_info("# logical channels=%d\n", conf->nvc);
1556 pr_info("level 3 pkt len=%d\n", conf->pktlen);
1557 pr_info("my address=%d\n", conf->locaddr);
1558 pr_info("remote address=%d\n", conf->remaddr);
1559 pr_info("t1=%d seconds\n", conf->t1);
1560 pr_info("t2=%d seconds\n", conf->t2);
1561 pr_info("t21=%d seconds\n", conf->t21);
1562 pr_info("# PVCs=%d\n", conf->npvc);
1563 pr_info("t23=%d seconds\n", conf->t23);
1564 pr_info("flags=0x%x\n", conf->flags);
1565}
1566
1567static void cycx_x25_dump_stats(struct cycx_x25_stats *stats)
1568{
1569 pr_info("X.25 statistics\n");
1570 pr_info("--------------\n");
1571 pr_info("rx_crc_errors=%d\n", stats->rx_crc_errors);
1572 pr_info("rx_over_errors=%d\n", stats->rx_over_errors);
1573 pr_info("n2_tx_frames=%d\n", stats->n2_tx_frames);
1574 pr_info("n2_rx_frames=%d\n", stats->n2_rx_frames);
1575 pr_info("tx_timeouts=%d\n", stats->tx_timeouts);
1576 pr_info("rx_timeouts=%d\n", stats->rx_timeouts);
1577 pr_info("n3_tx_packets=%d\n", stats->n3_tx_packets);
1578 pr_info("n3_rx_packets=%d\n", stats->n3_rx_packets);
1579 pr_info("tx_aborts=%d\n", stats->tx_aborts);
1580 pr_info("rx_aborts=%d\n", stats->rx_aborts);
1581}
1582
1583static void cycx_x25_dump_devs(struct wan_device *wandev)
1584{
1585 struct net_device *dev = wandev->dev;
1586
1587 pr_info("X.25 dev states\n");
1588 pr_info("name: addr: txoff: protocol:\n");
1589 pr_info("---------------------------------------\n");
1590
1591 while(dev) {
1592 struct cycx_x25_channel *chan = netdev_priv(dev);
1593
1594 pr_info("%-5.5s %-15.15s %d ETH_P_%s\n",
1595 chan->name, chan->addr, netif_queue_stopped(dev),
1596 chan->protocol == ETH_P_IP ? "IP" : "X25");
1597 dev = chan->slave;
1598 }
1599}
1600
1601#endif /* CYCLOMX_X25_DEBUG */
1602/* End */
diff --git a/include/linux/cyclomx.h b/include/linux/cyclomx.h
deleted file mode 100644
index b88f7f428e58..000000000000
--- a/include/linux/cyclomx.h
+++ /dev/null
@@ -1,77 +0,0 @@
1#ifndef _CYCLOMX_H
2#define _CYCLOMX_H
3/*
4* cyclomx.h Cyclom 2X WAN Link Driver.
5* User-level API definitions.
6*
7* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
8*
9* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
10*
11* Based on wanpipe.h by Gene Kozin <genek@compuserve.com>
12*
13* This program is free software; you can redistribute it and/or
14* modify it under the terms of the GNU General Public License
15* as published by the Free Software Foundation; either version
16* 2 of the License, or (at your option) any later version.
17* ============================================================================
18* 2000/07/13 acme remove crap #if KERNEL_VERSION > blah
19* 2000/01/21 acme rename cyclomx_open to cyclomx_mod_inc_use_count
20* and cyclomx_close to cyclomx_mod_dec_use_count
21* 1999/05/19 acme wait_queue_head_t wait_stats(support for 2.3.*)
22* 1999/01/03 acme judicious use of data types
23* 1998/12/27 acme cleanup: PACKED not needed
24* 1998/08/08 acme Version 0.0.1
25*/
26
27#include <linux/wanrouter.h>
28#include <linux/spinlock.h>
29
30#ifdef __KERNEL__
31/* Kernel Interface */
32
33#include <linux/cycx_drv.h> /* Cyclom 2X support module API definitions */
34#include <linux/cycx_cfm.h> /* Cyclom 2X firmware module definitions */
35#ifdef CONFIG_CYCLOMX_X25
36#include <linux/cycx_x25.h>
37#endif
38
39/* Adapter Data Space.
40 * This structure is needed because we handle multiple cards, otherwise
41 * static data would do it.
42 */
43struct cycx_device {
44 char devname[WAN_DRVNAME_SZ + 1];/* card name */
45 struct cycx_hw hw; /* hardware configuration */
46 struct wan_device wandev; /* WAN device data space */
47 u32 state_tick; /* link state timestamp */
48 spinlock_t lock;
49 char in_isr; /* interrupt-in-service flag */
50 char buff_int_mode_unbusy; /* flag for carrying out dev_tint */
51 wait_queue_head_t wait_stats; /* to wait for the STATS indication */
52 void __iomem *mbox; /* -> mailbox */
53 void (*isr)(struct cycx_device* card); /* interrupt service routine */
54 int (*exec)(struct cycx_device* card, void* u_cmd, void* u_data);
55 union {
56#ifdef CONFIG_CYCLOMX_X25
57 struct { /* X.25 specific data */
58 u32 lo_pvc;
59 u32 hi_pvc;
60 u32 lo_svc;
61 u32 hi_svc;
62 struct cycx_x25_stats stats;
63 spinlock_t lock;
64 u32 connection_keys;
65 } x;
66#endif
67 } u;
68};
69
70/* Public Functions */
71void cycx_set_state(struct cycx_device *card, int state);
72
73#ifdef CONFIG_CYCLOMX_X25
74int cycx_x25_wan_init(struct cycx_device *card, wandev_conf_t *conf);
75#endif
76#endif /* __KERNEL__ */
77#endif /* _CYCLOMX_H */
diff --git a/include/linux/cycx_drv.h b/include/linux/cycx_drv.h
deleted file mode 100644
index 12fe6b0bfcff..000000000000
--- a/include/linux/cycx_drv.h
+++ /dev/null
@@ -1,64 +0,0 @@
1/*
2* cycx_drv.h CYCX Support Module. Kernel API Definitions.
3*
4* Author: Arnaldo Carvalho de Melo <acme@conectiva.com.br>
5*
6* Copyright: (c) 1998-2003 Arnaldo Carvalho de Melo
7*
8* Based on sdladrv.h by Gene Kozin <genek@compuserve.com>
9*
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* 1999/10/23 acme cycxhw_t cleanup
16* 1999/01/03 acme more judicious use of data types...
17* uclong, ucchar, etc deleted, the u8, u16, u32
18* types are the portable way to go.
19* 1999/01/03 acme judicious use of data types... u16, u32, etc
20* 1998/12/26 acme FIXED_BUFFERS, CONF_OFFSET,
21* removal of cy_read{bwl}
22* 1998/08/08 acme Initial version.
23*/
24#ifndef _CYCX_DRV_H
25#define _CYCX_DRV_H
26
27#define CYCX_WINDOWSIZE 0x4000 /* default dual-port memory window size */
28#define GEN_CYCX_INTR 0x02
29#define RST_ENABLE 0x04
30#define START_CPU 0x06
31#define RST_DISABLE 0x08
32#define FIXED_BUFFERS 0x08
33#define TEST_PATTERN 0xaa55
34#define CMD_OFFSET 0x20
35#define CONF_OFFSET 0x0380
36#define RESET_OFFSET 0x3c00 /* For reset file load */
37#define DATA_OFFSET 0x0100 /* For code and data files load */
38#define START_OFFSET 0x3ff0 /* 80186 starts here */
39
40/**
41 * struct cycx_hw - Adapter hardware configuration
42 * @fwid - firmware ID
43 * @irq - interrupt request level
44 * @dpmbase - dual-port memory base
45 * @dpmsize - dual-port memory size
46 * @reserved - reserved for future use
47 */
48struct cycx_hw {
49 u32 fwid;
50 int irq;
51 void __iomem *dpmbase;
52 u32 dpmsize;
53 u32 reserved[5];
54};
55
56/* Function Prototypes */
57extern int cycx_setup(struct cycx_hw *hw, void *sfm, u32 len, unsigned long base);
58extern int cycx_down(struct cycx_hw *hw);
59extern int cycx_peek(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
60extern int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
61extern int cycx_exec(void __iomem *addr);
62
63extern void cycx_intr(struct cycx_hw *hw);
64#endif /* _CYCX_DRV_H */
diff --git a/include/linux/wanrouter.h b/include/linux/wanrouter.h
index cec4b4159767..8198a63cf459 100644
--- a/include/linux/wanrouter.h
+++ b/include/linux/wanrouter.h
@@ -1,129 +1,10 @@
1/***************************************************************************** 1/*
2* wanrouter.h Definitions for the WAN Multiprotocol Router Module. 2 * wanrouter.h Legacy declarations kept around until X25 is removed
3* This module provides API and common services for WAN Link 3 */
4* Drivers and is completely hardware-independent. 4
5*
6* Author: Nenad Corbic <ncorbic@sangoma.com>
7* Gideon Hack
8* Additions: Arnaldo Melo
9*
10* Copyright: (c) 1995-2000 Sangoma Technologies Inc.
11*
12* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License
14* as published by the Free Software Foundation; either version
15* 2 of the License, or (at your option) any later version.
16* ============================================================================
17* Jul 21, 2000 Nenad Corbic Added WAN_FT1_READY State
18* Feb 24, 2000 Nenad Corbic Added support for socket based x25api
19* Jan 28, 2000 Nenad Corbic Added support for the ASYNC protocol.
20* Oct 04, 1999 Nenad Corbic Updated for 2.1.0 release
21* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
22* May 23, 1999 Arnaldo Melo Added local_addr to wanif_conf_t
23* WAN_DISCONNECTING state added
24* Jul 20, 1998 David Fong Added Inverse ARP options to 'wanif_conf_t'
25* Jun 12, 1998 David Fong Added Cisco HDLC support.
26* Dec 16, 1997 Jaspreet Singh Moved 'enable_IPX' and 'network_number' to
27* 'wanif_conf_t'
28* Dec 05, 1997 Jaspreet Singh Added 'pap', 'chap' to 'wanif_conf_t'
29* Added 'authenticator' to 'wan_ppp_conf_t'
30* Nov 06, 1997 Jaspreet Singh Changed Router Driver version to 1.1 from 1.0
31* Oct 20, 1997 Jaspreet Singh Added 'cir','bc','be' and 'mc' to 'wanif_conf_t'
32* Added 'enable_IPX' and 'network_number' to
33* 'wan_device_t'. Also added defines for
34* UDP PACKET TYPE, Interrupt test, critical values
35* for RACE conditions.
36* Oct 05, 1997 Jaspreet Singh Added 'dlci_num' and 'dlci[100]' to
37* 'wan_fr_conf_t' to configure a list of dlci(s)
38* for a NODE
39* Jul 07, 1997 Jaspreet Singh Added 'ttl' to 'wandev_conf_t' & 'wan_device_t'
40* May 29, 1997 Jaspreet Singh Added 'tx_int_enabled' to 'wan_device_t'
41* May 21, 1997 Jaspreet Singh Added 'udp_port' to 'wan_device_t'
42* Apr 25, 1997 Farhan Thawar Added 'udp_port' to 'wandev_conf_t'
43* Jan 16, 1997 Gene Kozin router_devlist made public
44* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h).
45*****************************************************************************/
46#ifndef _ROUTER_H 5#ifndef _ROUTER_H
47#define _ROUTER_H 6#define _ROUTER_H
48 7
49#include <uapi/linux/wanrouter.h> 8#include <uapi/linux/wanrouter.h>
50 9
51/****** Kernel Interface ****************************************************/
52
53#include <linux/fs.h> /* support for device drivers */
54#include <linux/proc_fs.h> /* proc filesystem pragmatics */
55#include <linux/netdevice.h> /* support for network drivers */
56#include <linux/spinlock.h> /* Support for SMP Locking */
57
58/*----------------------------------------------------------------------------
59 * WAN device data space.
60 */
61struct wan_device {
62 unsigned magic; /* magic number */
63 char* name; /* -> WAN device name (ASCIIZ) */
64 void* private; /* -> driver private data */
65 unsigned config_id; /* Configuration ID */
66 /****** hardware configuration ******/
67 unsigned ioport; /* adapter I/O port base #1 */
68 char S514_cpu_no[1]; /* PCI CPU Number */
69 unsigned char S514_slot_no; /* PCI Slot Number */
70 unsigned long maddr; /* dual-port memory address */
71 unsigned msize; /* dual-port memory size */
72 int irq; /* interrupt request level */
73 int dma; /* DMA request level */
74 unsigned bps; /* data transfer rate */
75 unsigned mtu; /* max physical transmit unit size */
76 unsigned udp_port; /* UDP port for management */
77 unsigned char ttl; /* Time To Live for UDP security */
78 unsigned enable_tx_int; /* Transmit Interrupt enabled or not */
79 char interface; /* RS-232/V.35, etc. */
80 char clocking; /* external/internal */
81 char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */
82 char station; /* DTE/DCE, primary/secondary, etc. */
83 char connection; /* permanent/switched/on-demand */
84 char signalling; /* Signalling RS232 or V35 */
85 char read_mode; /* read mode: Polling or interrupt */
86 char new_if_cnt; /* Number of interfaces per wanpipe */
87 char del_if_cnt; /* Number of times del_if() gets called */
88 unsigned char piggyback; /* Piggibacking a port */
89 unsigned hw_opt[4]; /* other hardware options */
90 /****** status and statistics *******/
91 char state; /* device state */
92 char api_status; /* device api status */
93 struct net_device_stats stats; /* interface statistics */
94 unsigned reserved[16]; /* reserved for future use */
95 unsigned long critical; /* critical section flag */
96 spinlock_t lock; /* Support for SMP Locking */
97
98 /****** device management methods ***/
99 int (*setup) (struct wan_device *wandev, wandev_conf_t *conf);
100 int (*shutdown) (struct wan_device *wandev);
101 int (*update) (struct wan_device *wandev);
102 int (*ioctl) (struct wan_device *wandev, unsigned cmd,
103 unsigned long arg);
104 int (*new_if)(struct wan_device *wandev, struct net_device *dev,
105 wanif_conf_t *conf);
106 int (*del_if)(struct wan_device *wandev, struct net_device *dev);
107 /****** maintained by the router ****/
108 struct wan_device* next; /* -> next device */
109 struct net_device* dev; /* list of network interfaces */
110 unsigned ndev; /* number of interfaces */
111 struct proc_dir_entry *dent; /* proc filesystem entry */
112};
113
114/* Public functions available for device drivers */
115extern int register_wan_device(struct wan_device *wandev);
116extern int unregister_wan_device(char *name);
117
118/* Proc interface functions. These must not be called by the drivers! */
119extern int wanrouter_proc_init(void);
120extern void wanrouter_proc_cleanup(void);
121extern int wanrouter_proc_add(struct wan_device *wandev);
122extern int wanrouter_proc_delete(struct wan_device *wandev);
123extern long wanrouter_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
124
125/* Public Data */
126/* list of registered devices */
127extern struct wan_device *wanrouter_router_devlist;
128
129#endif /* _ROUTER_H */ 10#endif /* _ROUTER_H */
diff --git a/include/uapi/linux/wanrouter.h b/include/uapi/linux/wanrouter.h
index 7617df2833d5..498d6c12c666 100644
--- a/include/uapi/linux/wanrouter.h
+++ b/include/uapi/linux/wanrouter.h
@@ -1,363 +1,9 @@
1/*****************************************************************************
2* wanrouter.h Definitions for the WAN Multiprotocol Router Module.
3* This module provides API and common services for WAN Link
4* Drivers and is completely hardware-independent.
5*
6* Author: Nenad Corbic <ncorbic@sangoma.com>
7* Gideon Hack
8* Additions: Arnaldo Melo
9*
10* Copyright: (c) 1995-2000 Sangoma Technologies Inc.
11*
12* This program is free software; you can redistribute it and/or
13* modify it under the terms of the GNU General Public License
14* as published by the Free Software Foundation; either version
15* 2 of the License, or (at your option) any later version.
16* ============================================================================
17* Jul 21, 2000 Nenad Corbic Added WAN_FT1_READY State
18* Feb 24, 2000 Nenad Corbic Added support for socket based x25api
19* Jan 28, 2000 Nenad Corbic Added support for the ASYNC protocol.
20* Oct 04, 1999 Nenad Corbic Updated for 2.1.0 release
21* Jun 02, 1999 Gideon Hack Added support for the S514 adapter.
22* May 23, 1999 Arnaldo Melo Added local_addr to wanif_conf_t
23* WAN_DISCONNECTING state added
24* Jul 20, 1998 David Fong Added Inverse ARP options to 'wanif_conf_t'
25* Jun 12, 1998 David Fong Added Cisco HDLC support.
26* Dec 16, 1997 Jaspreet Singh Moved 'enable_IPX' and 'network_number' to
27* 'wanif_conf_t'
28* Dec 05, 1997 Jaspreet Singh Added 'pap', 'chap' to 'wanif_conf_t'
29* Added 'authenticator' to 'wan_ppp_conf_t'
30* Nov 06, 1997 Jaspreet Singh Changed Router Driver version to 1.1 from 1.0
31* Oct 20, 1997 Jaspreet Singh Added 'cir','bc','be' and 'mc' to 'wanif_conf_t'
32* Added 'enable_IPX' and 'network_number' to
33* 'wan_device_t'. Also added defines for
34* UDP PACKET TYPE, Interrupt test, critical values
35* for RACE conditions.
36* Oct 05, 1997 Jaspreet Singh Added 'dlci_num' and 'dlci[100]' to
37* 'wan_fr_conf_t' to configure a list of dlci(s)
38* for a NODE
39* Jul 07, 1997 Jaspreet Singh Added 'ttl' to 'wandev_conf_t' & 'wan_device_t'
40* May 29, 1997 Jaspreet Singh Added 'tx_int_enabled' to 'wan_device_t'
41* May 21, 1997 Jaspreet Singh Added 'udp_port' to 'wan_device_t'
42* Apr 25, 1997 Farhan Thawar Added 'udp_port' to 'wandev_conf_t'
43* Jan 16, 1997 Gene Kozin router_devlist made public
44* Jan 02, 1997 Gene Kozin Initial version (based on wanpipe.h).
45*****************************************************************************/
46
47#ifndef _UAPI_ROUTER_H
48#define _UAPI_ROUTER_H
49
50#define ROUTER_NAME "wanrouter" /* in case we ever change it */
51#define ROUTER_VERSION 1 /* version number */
52#define ROUTER_RELEASE 1 /* release (minor version) number */
53#define ROUTER_IOCTL 'W' /* for IOCTL calls */
54#define ROUTER_MAGIC 0x524D4157L /* signature: 'WANR' reversed */
55
56/* IOCTL codes for /proc/router/<device> entries (up to 255) */
57enum router_ioctls
58{
59 ROUTER_SETUP = ROUTER_IOCTL<<8, /* configure device */
60 ROUTER_DOWN, /* shut down device */
61 ROUTER_STAT, /* get device status */
62 ROUTER_IFNEW, /* add interface */
63 ROUTER_IFDEL, /* delete interface */
64 ROUTER_IFSTAT, /* get interface status */
65 ROUTER_USER = (ROUTER_IOCTL<<8)+16, /* driver-specific calls */
66 ROUTER_USER_MAX = (ROUTER_IOCTL<<8)+31
67};
68
69/* identifiers for displaying proc file data for dual port adapters */
70#define PROC_DATA_PORT_0 0x8000 /* the data is for port 0 */
71#define PROC_DATA_PORT_1 0x8001 /* the data is for port 1 */
72
73/* NLPID for packet encapsulation (ISO/IEC TR 9577) */
74#define NLPID_IP 0xCC /* Internet Protocol Datagram */
75#define NLPID_SNAP 0x80 /* IEEE Subnetwork Access Protocol */
76#define NLPID_CLNP 0x81 /* ISO/IEC 8473 */
77#define NLPID_ESIS 0x82 /* ISO/IEC 9542 */
78#define NLPID_ISIS 0x83 /* ISO/IEC ISIS */
79#define NLPID_Q933 0x08 /* CCITT Q.933 */
80
81/* Miscellaneous */
82#define WAN_IFNAME_SZ 15 /* max length of the interface name */
83#define WAN_DRVNAME_SZ 15 /* max length of the link driver name */
84#define WAN_ADDRESS_SZ 31 /* max length of the WAN media address */
85#define USED_BY_FIELD 8 /* max length of the used by field */
86
87/* Defines for UDP PACKET TYPE */
88#define UDP_PTPIPE_TYPE 0x01
89#define UDP_FPIPE_TYPE 0x02
90#define UDP_CPIPE_TYPE 0x03
91#define UDP_DRVSTATS_TYPE 0x04
92#define UDP_INVALID_TYPE 0x05
93
94/* Command return code */
95#define CMD_OK 0 /* normal firmware return code */
96#define CMD_TIMEOUT 0xFF /* firmware command timed out */
97
98/* UDP Packet Management */
99#define UDP_PKT_FRM_STACK 0x00
100#define UDP_PKT_FRM_NETWORK 0x01
101
102/* Maximum interrupt test counter */
103#define MAX_INTR_TEST_COUNTER 100
104
105/* Critical Values for RACE conditions*/
106#define CRITICAL_IN_ISR 0xA1
107#define CRITICAL_INTR_HANDLED 0xB1
108
109/****** Data Types **********************************************************/
110
111/*----------------------------------------------------------------------------
112 * X.25-specific link-level configuration.
113 */
114typedef struct wan_x25_conf
115{
116 unsigned lo_pvc; /* lowest permanent circuit number */
117 unsigned hi_pvc; /* highest permanent circuit number */
118 unsigned lo_svc; /* lowest switched circuit number */
119 unsigned hi_svc; /* highest switched circuit number */
120 unsigned hdlc_window; /* HDLC window size (1..7) */
121 unsigned pkt_window; /* X.25 packet window size (1..7) */
122 unsigned t1; /* HDLC timer T1, sec (1..30) */
123 unsigned t2; /* HDLC timer T2, sec (0..29) */
124 unsigned t4; /* HDLC supervisory frame timer = T4 * T1 */
125 unsigned n2; /* HDLC retransmission limit (1..30) */
126 unsigned t10_t20; /* X.25 RESTART timeout, sec (1..255) */
127 unsigned t11_t21; /* X.25 CALL timeout, sec (1..255) */
128 unsigned t12_t22; /* X.25 RESET timeout, sec (1..255) */
129 unsigned t13_t23; /* X.25 CLEAR timeout, sec (1..255) */
130 unsigned t16_t26; /* X.25 INTERRUPT timeout, sec (1..255) */
131 unsigned t28; /* X.25 REGISTRATION timeout, sec (1..255) */
132 unsigned r10_r20; /* RESTART retransmission limit (0..250) */
133 unsigned r12_r22; /* RESET retransmission limit (0..250) */
134 unsigned r13_r23; /* CLEAR retransmission limit (0..250) */
135 unsigned ccitt_compat; /* compatibility mode: 1988/1984/1980 */
136 unsigned x25_conf_opt; /* User defined x25 config optoins */
137 unsigned char LAPB_hdlc_only; /* Run in HDLC only mode */
138 unsigned char logging; /* Control connection logging */
139 unsigned char oob_on_modem; /* Whether to send modem status to the user app */
140} wan_x25_conf_t;
141
142/*----------------------------------------------------------------------------
143 * Frame relay specific link-level configuration.
144 */
145typedef struct wan_fr_conf
146{
147 unsigned signalling; /* local in-channel signalling type */
148 unsigned t391; /* link integrity verification timer */
149 unsigned t392; /* polling verification timer */
150 unsigned n391; /* full status polling cycle counter */
151 unsigned n392; /* error threshold counter */
152 unsigned n393; /* monitored events counter */
153 unsigned dlci_num; /* number of DLCs (access node) */
154 unsigned dlci[100]; /* List of all DLCIs */
155} wan_fr_conf_t;
156
157/*----------------------------------------------------------------------------
158 * PPP-specific link-level configuration.
159 */
160typedef struct wan_ppp_conf
161{
162 unsigned restart_tmr; /* restart timer */
163 unsigned auth_rsrt_tmr; /* authentication timer */
164 unsigned auth_wait_tmr; /* authentication timer */
165 unsigned mdm_fail_tmr; /* modem failure timer */
166 unsigned dtr_drop_tmr; /* DTR drop timer */
167 unsigned connect_tmout; /* connection timeout */
168 unsigned conf_retry; /* max. retry */
169 unsigned term_retry; /* max. retry */
170 unsigned fail_retry; /* max. retry */
171 unsigned auth_retry; /* max. retry */
172 unsigned auth_options; /* authentication opt. */
173 unsigned ip_options; /* IP options */
174 char authenticator; /* AUTHENTICATOR or not */
175 char ip_mode; /* Static/Host/Peer */
176} wan_ppp_conf_t;
177
178/*----------------------------------------------------------------------------
179 * CHDLC-specific link-level configuration.
180 */
181typedef struct wan_chdlc_conf
182{
183 unsigned char ignore_dcd; /* Protocol options: */
184 unsigned char ignore_cts; /* Ignore these to determine */
185 unsigned char ignore_keepalive; /* link status (Yes or No) */
186 unsigned char hdlc_streaming; /* hdlc_streaming mode (Y/N) */
187 unsigned char receive_only; /* no transmit buffering (Y/N) */
188 unsigned keepalive_tx_tmr; /* transmit keepalive timer */
189 unsigned keepalive_rx_tmr; /* receive keepalive timer */
190 unsigned keepalive_err_margin; /* keepalive_error_tolerance */
191 unsigned slarp_timer; /* SLARP request timer */
192} wan_chdlc_conf_t;
193
194
195/*----------------------------------------------------------------------------
196 * WAN device configuration. Passed to ROUTER_SETUP IOCTL.
197 */
198typedef struct wandev_conf
199{
200 unsigned magic; /* magic number (for verification) */
201 unsigned config_id; /* configuration structure identifier */
202 /****** hardware configuration ******/
203 unsigned ioport; /* adapter I/O port base */
204 unsigned long maddr; /* dual-port memory address */
205 unsigned msize; /* dual-port memory size */
206 int irq; /* interrupt request level */
207 int dma; /* DMA request level */
208 char S514_CPU_no[1]; /* S514 PCI adapter CPU number ('A' or 'B') */
209 unsigned PCI_slot_no; /* S514 PCI adapter slot number */
210 char auto_pci_cfg; /* S515 PCI automatic slot detection */
211 char comm_port; /* Communication Port (PRI=0, SEC=1) */
212 unsigned bps; /* data transfer rate */
213 unsigned mtu; /* maximum transmit unit size */
214 unsigned udp_port; /* UDP port for management */
215 unsigned char ttl; /* Time To Live for UDP security */
216 unsigned char ft1; /* FT1 Configurator Option */
217 char interface; /* RS-232/V.35, etc. */
218 char clocking; /* external/internal */
219 char line_coding; /* NRZ/NRZI/FM0/FM1, etc. */
220 char station; /* DTE/DCE, primary/secondary, etc. */
221 char connection; /* permanent/switched/on-demand */
222 char read_mode; /* read mode: Polling or interrupt */
223 char receive_only; /* disable tx buffers */
224 char tty; /* Create a fake tty device */
225 unsigned tty_major; /* Major number for wanpipe tty device */
226 unsigned tty_minor; /* Minor number for wanpipe tty device */
227 unsigned tty_mode; /* TTY operation mode SYNC or ASYNC */
228 char backup; /* Backup Mode */
229 unsigned hw_opt[4]; /* other hardware options */
230 unsigned reserved[4];
231 /****** arbitrary data ***************/
232 unsigned data_size; /* data buffer size */
233 void* data; /* data buffer, e.g. firmware */
234 union /****** protocol-specific ************/
235 {
236 wan_x25_conf_t x25; /* X.25 configuration */
237 wan_ppp_conf_t ppp; /* PPP configuration */
238 wan_fr_conf_t fr; /* frame relay configuration */
239 wan_chdlc_conf_t chdlc; /* Cisco HDLC configuration */
240 } u;
241} wandev_conf_t;
242
243/* 'config_id' definitions */
244#define WANCONFIG_X25 101 /* X.25 link */
245#define WANCONFIG_FR 102 /* frame relay link */
246#define WANCONFIG_PPP 103 /* synchronous PPP link */
247#define WANCONFIG_CHDLC 104 /* Cisco HDLC Link */
248#define WANCONFIG_BSC 105 /* BiSync Streaming */
249#define WANCONFIG_HDLC 106 /* HDLC Support */
250#define WANCONFIG_MPPP 107 /* Multi Port PPP over RAW CHDLC */
251
252/* 1/*
253 * Configuration options defines. 2 * wanrouter.h Legacy declarations kept around until X25 is removed
254 */ 3 */
255/* general options */
256#define WANOPT_OFF 0
257#define WANOPT_ON 1
258#define WANOPT_NO 0
259#define WANOPT_YES 1
260
261/* intercace options */
262#define WANOPT_RS232 0
263#define WANOPT_V35 1
264
265/* data encoding options */
266#define WANOPT_NRZ 0
267#define WANOPT_NRZI 1
268#define WANOPT_FM0 2
269#define WANOPT_FM1 3
270
271/* link type options */
272#define WANOPT_POINTTOPOINT 0 /* RTS always active */
273#define WANOPT_MULTIDROP 1 /* RTS is active when transmitting */
274
275/* clocking options */
276#define WANOPT_EXTERNAL 0
277#define WANOPT_INTERNAL 1
278
279/* station options */
280#define WANOPT_DTE 0
281#define WANOPT_DCE 1
282#define WANOPT_CPE 0
283#define WANOPT_NODE 1
284#define WANOPT_SECONDARY 0
285#define WANOPT_PRIMARY 1
286
287/* connection options */
288#define WANOPT_PERMANENT 0 /* DTR always active */
289#define WANOPT_SWITCHED 1 /* use DTR to setup link (dial-up) */
290#define WANOPT_ONDEMAND 2 /* activate DTR only before sending */
291
292/* frame relay in-channel signalling */
293#define WANOPT_FR_ANSI 1 /* ANSI T1.617 Annex D */
294#define WANOPT_FR_Q933 2 /* ITU Q.933A */
295#define WANOPT_FR_LMI 3 /* LMI */
296
297/* PPP IP Mode Options */
298#define WANOPT_PPP_STATIC 0
299#define WANOPT_PPP_HOST 1
300#define WANOPT_PPP_PEER 2
301
302/* ASY Mode Options */
303#define WANOPT_ONE 1
304#define WANOPT_TWO 2
305#define WANOPT_ONE_AND_HALF 3
306
307#define WANOPT_NONE 0
308#define WANOPT_ODD 1
309#define WANOPT_EVEN 2
310
311/* CHDLC Protocol Options */
312/* DF Commented out for now.
313
314#define WANOPT_CHDLC_NO_DCD IGNORE_DCD_FOR_LINK_STAT
315#define WANOPT_CHDLC_NO_CTS IGNORE_CTS_FOR_LINK_STAT
316#define WANOPT_CHDLC_NO_KEEPALIVE IGNORE_KPALV_FOR_LINK_STAT
317*/
318
319/* Port options */
320#define WANOPT_PRI 0
321#define WANOPT_SEC 1
322/* read mode */
323#define WANOPT_INTR 0
324#define WANOPT_POLL 1
325 4
326 5#ifndef _UAPI_ROUTER_H
327#define WANOPT_TTY_SYNC 0 6#define _UAPI_ROUTER_H
328#define WANOPT_TTY_ASYNC 1
329/*----------------------------------------------------------------------------
330 * WAN Link Status Info (for ROUTER_STAT IOCTL).
331 */
332typedef struct wandev_stat
333{
334 unsigned state; /* link state */
335 unsigned ndev; /* number of configured interfaces */
336
337 /* link/interface configuration */
338 unsigned connection; /* permanent/switched/on-demand */
339 unsigned media_type; /* Frame relay/PPP/X.25/SDLC, etc. */
340 unsigned mtu; /* max. transmit unit for this device */
341
342 /* physical level statistics */
343 unsigned modem_status; /* modem status */
344 unsigned rx_frames; /* received frames count */
345 unsigned rx_overruns; /* receiver overrun error count */
346 unsigned rx_crc_err; /* receive CRC error count */
347 unsigned rx_aborts; /* received aborted frames count */
348 unsigned rx_bad_length; /* unexpetedly long/short frames count */
349 unsigned rx_dropped; /* frames discarded at device level */
350 unsigned tx_frames; /* transmitted frames count */
351 unsigned tx_underruns; /* aborted transmissions (underruns) count */
352 unsigned tx_timeouts; /* transmission timeouts */
353 unsigned tx_rejects; /* other transmit errors */
354
355 /* media level statistics */
356 unsigned rx_bad_format; /* frames with invalid format */
357 unsigned rx_bad_addr; /* frames with invalid media address */
358 unsigned tx_retries; /* frames re-transmitted */
359 unsigned reserved[16]; /* reserved for future use */
360} wandev_stat_t;
361 7
362/* 'state' defines */ 8/* 'state' defines */
363enum wan_states 9enum wan_states
@@ -365,88 +11,7 @@ enum wan_states
365 WAN_UNCONFIGURED, /* link/channel is not configured */ 11 WAN_UNCONFIGURED, /* link/channel is not configured */
366 WAN_DISCONNECTED, /* link/channel is disconnected */ 12 WAN_DISCONNECTED, /* link/channel is disconnected */
367 WAN_CONNECTING, /* connection is in progress */ 13 WAN_CONNECTING, /* connection is in progress */
368 WAN_CONNECTED, /* link/channel is operational */ 14 WAN_CONNECTED /* link/channel is operational */
369 WAN_LIMIT, /* for verification only */
370 WAN_DUALPORT, /* for Dual Port cards */
371 WAN_DISCONNECTING,
372 WAN_FT1_READY /* FT1 Configurator Ready */
373}; 15};
374 16
375enum {
376 WAN_LOCAL_IP,
377 WAN_POINTOPOINT_IP,
378 WAN_NETMASK_IP,
379 WAN_BROADCAST_IP
380};
381
382/* 'modem_status' masks */
383#define WAN_MODEM_CTS 0x0001 /* CTS line active */
384#define WAN_MODEM_DCD 0x0002 /* DCD line active */
385#define WAN_MODEM_DTR 0x0010 /* DTR line active */
386#define WAN_MODEM_RTS 0x0020 /* RTS line active */
387
388/*----------------------------------------------------------------------------
389 * WAN interface (logical channel) configuration (for ROUTER_IFNEW IOCTL).
390 */
391typedef struct wanif_conf
392{
393 unsigned magic; /* magic number */
394 unsigned config_id; /* configuration identifier */
395 char name[WAN_IFNAME_SZ+1]; /* interface name, ASCIIZ */
396 char addr[WAN_ADDRESS_SZ+1]; /* media address, ASCIIZ */
397 char usedby[USED_BY_FIELD]; /* used by API or WANPIPE */
398 unsigned idle_timeout; /* sec, before disconnecting */
399 unsigned hold_timeout; /* sec, before re-connecting */
400 unsigned cir; /* Committed Information Rate fwd,bwd*/
401 unsigned bc; /* Committed Burst Size fwd, bwd */
402 unsigned be; /* Excess Burst Size fwd, bwd */
403 unsigned char enable_IPX; /* Enable or Disable IPX */
404 unsigned char inarp; /* Send Inverse ARP requests Y/N */
405 unsigned inarp_interval; /* sec, between InARP requests */
406 unsigned long network_number; /* Network Number for IPX */
407 char mc; /* Multicast on or off */
408 char local_addr[WAN_ADDRESS_SZ+1];/* local media address, ASCIIZ */
409 unsigned char port; /* board port */
410 unsigned char protocol; /* prococol used in this channel (TCPOX25 or X25) */
411 char pap; /* PAP enabled or disabled */
412 char chap; /* CHAP enabled or disabled */
413 unsigned char userid[511]; /* List of User Id */
414 unsigned char passwd[511]; /* List of passwords */
415 unsigned char sysname[31]; /* Name of the system */
416 unsigned char ignore_dcd; /* Protocol options: */
417 unsigned char ignore_cts; /* Ignore these to determine */
418 unsigned char ignore_keepalive; /* link status (Yes or No) */
419 unsigned char hdlc_streaming; /* Hdlc streaming mode (Y/N) */
420 unsigned keepalive_tx_tmr; /* transmit keepalive timer */
421 unsigned keepalive_rx_tmr; /* receive keepalive timer */
422 unsigned keepalive_err_margin; /* keepalive_error_tolerance */
423 unsigned slarp_timer; /* SLARP request timer */
424 unsigned char ttl; /* Time To Live for UDP security */
425 char interface; /* RS-232/V.35, etc. */
426 char clocking; /* external/internal */
427 unsigned bps; /* data transfer rate */
428 unsigned mtu; /* maximum transmit unit size */
429 unsigned char if_down; /* brind down interface when disconnected */
430 unsigned char gateway; /* Is this interface a gateway */
431 unsigned char true_if_encoding; /* Set the dev->type to true board protocol */
432
433 unsigned char asy_data_trans; /* async API options */
434 unsigned char rts_hs_for_receive; /* async Protocol options */
435 unsigned char xon_xoff_hs_for_receive;
436 unsigned char xon_xoff_hs_for_transmit;
437 unsigned char dcd_hs_for_transmit;
438 unsigned char cts_hs_for_transmit;
439 unsigned char async_mode;
440 unsigned tx_bits_per_char;
441 unsigned rx_bits_per_char;
442 unsigned stop_bits;
443 unsigned char parity;
444 unsigned break_timer;
445 unsigned inter_char_timer;
446 unsigned rx_complete_length;
447 unsigned xon_char;
448 unsigned xoff_char;
449 unsigned char receive_only; /* no transmit buffering (Y/N) */
450} wanif_conf_t;
451
452#endif /* _UAPI_ROUTER_H */ 17#endif /* _UAPI_ROUTER_H */
diff --git a/net/wanrouter/Kconfig b/net/wanrouter/Kconfig
deleted file mode 100644
index a157a2e64e18..000000000000
--- a/net/wanrouter/Kconfig
+++ /dev/null
@@ -1,27 +0,0 @@
1#
2# Configuration for WAN router
3#
4
5config WAN_ROUTER
6 tristate "WAN router (DEPRECATED)"
7 depends on EXPERIMENTAL
8 ---help---
9 Wide Area Networks (WANs), such as X.25, frame relay and leased
10 lines, are used to interconnect Local Area Networks (LANs) over vast
11 distances with data transfer rates significantly higher than those
12 achievable with commonly used asynchronous modem connections.
13 Usually, a quite expensive external device called a `WAN router' is
14 needed to connect to a WAN.
15
16 As an alternative, WAN routing can be built into the Linux kernel.
17 With relatively inexpensive WAN interface cards available on the
18 market, a perfectly usable router can be built for less than half
19 the price of an external router. If you have one of those cards and
20 wish to use your Linux box as a WAN router, say Y here and also to
21 the WAN driver for your card, below. You will then need the
22 wan-tools package which is available from <ftp://ftp.sangoma.com/>.
23
24 To compile WAN routing support as a module, choose M here: the
25 module will be called wanrouter.
26
27 If unsure, say N.
diff --git a/net/wanrouter/Makefile b/net/wanrouter/Makefile
deleted file mode 100644
index 4da14bc48078..000000000000
--- a/net/wanrouter/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
1#
2# Makefile for the Linux WAN router layer.
3#
4
5obj-$(CONFIG_WAN_ROUTER) += wanrouter.o
6
7wanrouter-y := wanproc.o wanmain.o
diff --git a/net/wanrouter/patchlevel b/net/wanrouter/patchlevel
deleted file mode 100644
index c043eea7767e..000000000000
--- a/net/wanrouter/patchlevel
+++ /dev/null
@@ -1 +0,0 @@
12.2.1
diff --git a/net/wanrouter/wanmain.c b/net/wanrouter/wanmain.c
deleted file mode 100644
index 2ab785064b7e..000000000000
--- a/net/wanrouter/wanmain.c
+++ /dev/null
@@ -1,782 +0,0 @@
1/*****************************************************************************
2* wanmain.c WAN Multiprotocol Router Module. Main code.
3*
4* This module is completely hardware-independent and provides
5* the following common services for the WAN Link Drivers:
6* o WAN device management (registering, unregistering)
7* o Network interface management
8* o Physical connection management (dial-up, incoming calls)
9* o Logical connection management (switched virtual circuits)
10* o Protocol encapsulation/decapsulation
11*
12* Author: Gideon Hack
13*
14* Copyright: (c) 1995-1999 Sangoma Technologies Inc.
15*
16* This program is free software; you can redistribute it and/or
17* modify it under the terms of the GNU General Public License
18* as published by the Free Software Foundation; either version
19* 2 of the License, or (at your option) any later version.
20* ============================================================================
21* Nov 24, 2000 Nenad Corbic Updated for 2.4.X kernels
22* Nov 07, 2000 Nenad Corbic Fixed the Mulit-Port PPP for kernels 2.2.16 and
23* greater.
24* Aug 2, 2000 Nenad Corbic Block the Multi-Port PPP from running on
25* kernels 2.2.16 or greater. The SyncPPP
26* has changed.
27* Jul 13, 2000 Nenad Corbic Added SyncPPP support
28* Added extra debugging in device_setup().
29* Oct 01, 1999 Gideon Hack Update for s514 PCI card
30* Dec 27, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
31* Jan 16, 1997 Gene Kozin router_devlist made public
32* Jan 31, 1997 Alan Cox Hacked it about a bit for 2.1
33* Jun 27, 1997 Alan Cox realigned with vendor code
34* Oct 15, 1997 Farhan Thawar changed wan_encapsulate to add a pad byte of 0
35* Apr 20, 1998 Alan Cox Fixed 2.1 symbols
36* May 17, 1998 K. Baranowski Fixed SNAP encapsulation in wan_encapsulate
37* Dec 15, 1998 Arnaldo Melo support for firmwares of up to 128000 bytes
38* check wandev->setup return value
39* Dec 22, 1998 Arnaldo Melo vmalloc/vfree used in device_setup to allocate
40* kernel memory and copy configuration data to
41* kernel space (for big firmwares)
42* Jun 02, 1999 Gideon Hack Updates for Linux 2.0.X and 2.2.X kernels.
43*****************************************************************************/
44
45#include <linux/stddef.h> /* offsetof(), etc. */
46#include <linux/capability.h>
47#include <linux/errno.h> /* return codes */
48#include <linux/kernel.h>
49#include <linux/module.h> /* support for loadable modules */
50#include <linux/slab.h> /* kmalloc(), kfree() */
51#include <linux/mutex.h>
52#include <linux/mm.h>
53#include <linux/string.h> /* inline mem*, str* functions */
54
55#include <asm/byteorder.h> /* htons(), etc. */
56#include <linux/wanrouter.h> /* WAN router API definitions */
57
58#include <linux/vmalloc.h> /* vmalloc, vfree */
59#include <asm/uaccess.h> /* copy_to/from_user */
60#include <linux/init.h> /* __initfunc et al. */
61
62#define DEV_TO_SLAVE(dev) (*((struct net_device **)netdev_priv(dev)))
63
64/*
65 * Function Prototypes
66 */
67
68/*
69 * WAN device IOCTL handlers
70 */
71
72static DEFINE_MUTEX(wanrouter_mutex);
73static int wanrouter_device_setup(struct wan_device *wandev,
74 wandev_conf_t __user *u_conf);
75static int wanrouter_device_stat(struct wan_device *wandev,
76 wandev_stat_t __user *u_stat);
77static int wanrouter_device_shutdown(struct wan_device *wandev);
78static int wanrouter_device_new_if(struct wan_device *wandev,
79 wanif_conf_t __user *u_conf);
80static int wanrouter_device_del_if(struct wan_device *wandev,
81 char __user *u_name);
82
83/*
84 * Miscellaneous
85 */
86
87static struct wan_device *wanrouter_find_device(char *name);
88static int wanrouter_delete_interface(struct wan_device *wandev, char *name);
89static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
90 __acquires(lock);
91static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
92 __releases(lock);
93
94
95
96/*
97 * Global Data
98 */
99
100static char wanrouter_fullname[] = "Sangoma WANPIPE Router";
101static char wanrouter_copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";
102static char wanrouter_modname[] = ROUTER_NAME; /* short module name */
103struct wan_device* wanrouter_router_devlist; /* list of registered devices */
104
105/*
106 * Organize Unique Identifiers for encapsulation/decapsulation
107 */
108
109#if 0
110static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };
111static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 };
112#endif
113
114static int __init wanrouter_init(void)
115{
116 int err;
117
118 printk(KERN_INFO "%s v%u.%u %s\n",
119 wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
120 wanrouter_copyright);
121
122 err = wanrouter_proc_init();
123 if (err)
124 printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
125 wanrouter_modname);
126
127 return err;
128}
129
130static void __exit wanrouter_cleanup (void)
131{
132 wanrouter_proc_cleanup();
133}
134
135/*
136 * This is just plain dumb. We should move the bugger to drivers/net/wan,
137 * slap it first in directory and make it module_init(). The only reason
138 * for subsys_initcall() here is that net goes after drivers (why, BTW?)
139 */
140subsys_initcall(wanrouter_init);
141module_exit(wanrouter_cleanup);
142
143/*
144 * Kernel APIs
145 */
146
147/*
148 * Register WAN device.
149 * o verify device credentials
150 * o create an entry for the device in the /proc/net/router directory
151 * o initialize internally maintained fields of the wan_device structure
152 * o link device data space to a singly-linked list
153 * o if it's the first device, then start kernel 'thread'
154 * o increment module use count
155 *
156 * Return:
157 * 0 Ok
158 * < 0 error.
159 *
160 * Context: process
161 */
162
163
164int register_wan_device(struct wan_device *wandev)
165{
166 int err, namelen;
167
168 if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC) ||
169 (wandev->name == NULL))
170 return -EINVAL;
171
172 namelen = strlen(wandev->name);
173 if (!namelen || (namelen > WAN_DRVNAME_SZ))
174 return -EINVAL;
175
176 if (wanrouter_find_device(wandev->name))
177 return -EEXIST;
178
179#ifdef WANDEBUG
180 printk(KERN_INFO "%s: registering WAN device %s\n",
181 wanrouter_modname, wandev->name);
182#endif
183
184 /*
185 * Register /proc directory entry
186 */
187 err = wanrouter_proc_add(wandev);
188 if (err) {
189 printk(KERN_INFO
190 "%s: can't create /proc/net/router/%s entry!\n",
191 wanrouter_modname, wandev->name);
192 return err;
193 }
194
195 /*
196 * Initialize fields of the wan_device structure maintained by the
197 * router and update local data.
198 */
199
200 wandev->ndev = 0;
201 wandev->dev = NULL;
202 wandev->next = wanrouter_router_devlist;
203 wanrouter_router_devlist = wandev;
204 return 0;
205}
206
207/*
208 * Unregister WAN device.
209 * o shut down device
210 * o unlink device data space from the linked list
211 * o delete device entry in the /proc/net/router directory
212 * o decrement module use count
213 *
214 * Return: 0 Ok
215 * <0 error.
216 * Context: process
217 */
218
219
220int unregister_wan_device(char *name)
221{
222 struct wan_device *wandev, *prev;
223
224 if (name == NULL)
225 return -EINVAL;
226
227 for (wandev = wanrouter_router_devlist, prev = NULL;
228 wandev && strcmp(wandev->name, name);
229 prev = wandev, wandev = wandev->next)
230 ;
231 if (wandev == NULL)
232 return -ENODEV;
233
234#ifdef WANDEBUG
235 printk(KERN_INFO "%s: unregistering WAN device %s\n",
236 wanrouter_modname, name);
237#endif
238
239 if (wandev->state != WAN_UNCONFIGURED)
240 wanrouter_device_shutdown(wandev);
241
242 if (prev)
243 prev->next = wandev->next;
244 else
245 wanrouter_router_devlist = wandev->next;
246
247 wanrouter_proc_delete(wandev);
248 return 0;
249}
250
251#if 0
252
253/*
254 * Encapsulate packet.
255 *
256 * Return: encapsulation header size
257 * < 0 - unsupported Ethertype
258 *
259 * Notes:
260 * 1. This function may be called on interrupt context.
261 */
262
263
264int wanrouter_encapsulate(struct sk_buff *skb, struct net_device *dev,
265 unsigned short type)
266{
267 int hdr_len = 0;
268
269 switch (type) {
270 case ETH_P_IP: /* IP datagram encapsulation */
271 hdr_len += 1;
272 skb_push(skb, 1);
273 skb->data[0] = NLPID_IP;
274 break;
275
276 case ETH_P_IPX: /* SNAP encapsulation */
277 case ETH_P_ARP:
278 hdr_len += 7;
279 skb_push(skb, 7);
280 skb->data[0] = 0;
281 skb->data[1] = NLPID_SNAP;
282 skb_copy_to_linear_data_offset(skb, 2, wanrouter_oui_ether,
283 sizeof(wanrouter_oui_ether));
284 *((unsigned short*)&skb->data[5]) = htons(type);
285 break;
286
287 default: /* Unknown packet type */
288 printk(KERN_INFO
289 "%s: unsupported Ethertype 0x%04X on interface %s!\n",
290 wanrouter_modname, type, dev->name);
291 hdr_len = -EINVAL;
292 }
293 return hdr_len;
294}
295
296
297/*
298 * Decapsulate packet.
299 *
300 * Return: Ethertype (in network order)
301 * 0 unknown encapsulation
302 *
303 * Notes:
304 * 1. This function may be called on interrupt context.
305 */
306
307
308__be16 wanrouter_type_trans(struct sk_buff *skb, struct net_device *dev)
309{
310 int cnt = skb->data[0] ? 0 : 1; /* there may be a pad present */
311 __be16 ethertype;
312
313 switch (skb->data[cnt]) {
314 case NLPID_IP: /* IP datagramm */
315 ethertype = htons(ETH_P_IP);
316 cnt += 1;
317 break;
318
319 case NLPID_SNAP: /* SNAP encapsulation */
320 if (memcmp(&skb->data[cnt + 1], wanrouter_oui_ether,
321 sizeof(wanrouter_oui_ether))){
322 printk(KERN_INFO
323 "%s: unsupported SNAP OUI %02X-%02X-%02X "
324 "on interface %s!\n", wanrouter_modname,
325 skb->data[cnt+1], skb->data[cnt+2],
326 skb->data[cnt+3], dev->name);
327 return 0;
328 }
329 ethertype = *((__be16*)&skb->data[cnt+4]);
330 cnt += 6;
331 break;
332
333 /* add other protocols, e.g. CLNP, ESIS, ISIS, if needed */
334
335 default:
336 printk(KERN_INFO
337 "%s: unsupported NLPID 0x%02X on interface %s!\n",
338 wanrouter_modname, skb->data[cnt], dev->name);
339 return 0;
340 }
341 skb->protocol = ethertype;
342 skb->pkt_type = PACKET_HOST; /* Physically point to point */
343 skb_pull(skb, cnt);
344 skb_reset_mac_header(skb);
345 return ethertype;
346}
347
348#endif /* 0 */
349
350/*
351 * WAN device IOCTL.
352 * o find WAN device associated with this node
353 * o execute requested action or pass command to the device driver
354 */
355
356long wanrouter_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
357{
358 struct inode *inode = file->f_path.dentry->d_inode;
359 int err = 0;
360 struct proc_dir_entry *dent;
361 struct wan_device *wandev;
362 void __user *data = (void __user *)arg;
363
364 if (!capable(CAP_NET_ADMIN))
365 return -EPERM;
366
367 if ((cmd >> 8) != ROUTER_IOCTL)
368 return -EINVAL;
369
370 dent = PDE(inode);
371 if ((dent == NULL) || (dent->data == NULL))
372 return -EINVAL;
373
374 wandev = dent->data;
375 if (wandev->magic != ROUTER_MAGIC)
376 return -EINVAL;
377
378 mutex_lock(&wanrouter_mutex);
379 switch (cmd) {
380 case ROUTER_SETUP:
381 err = wanrouter_device_setup(wandev, data);
382 break;
383
384 case ROUTER_DOWN:
385 err = wanrouter_device_shutdown(wandev);
386 break;
387
388 case ROUTER_STAT:
389 err = wanrouter_device_stat(wandev, data);
390 break;
391
392 case ROUTER_IFNEW:
393 err = wanrouter_device_new_if(wandev, data);
394 break;
395
396 case ROUTER_IFDEL:
397 err = wanrouter_device_del_if(wandev, data);
398 break;
399
400 case ROUTER_IFSTAT:
401 break;
402
403 default:
404 if ((cmd >= ROUTER_USER) &&
405 (cmd <= ROUTER_USER_MAX) &&
406 wandev->ioctl)
407 err = wandev->ioctl(wandev, cmd, arg);
408 else err = -EINVAL;
409 }
410 mutex_unlock(&wanrouter_mutex);
411 return err;
412}
413
414/*
415 * WAN Driver IOCTL Handlers
416 */
417
418/*
419 * Setup WAN link device.
420 * o verify user address space
421 * o allocate kernel memory and copy configuration data to kernel space
422 * o if configuration data includes extension, copy it to kernel space too
423 * o call driver's setup() entry point
424 */
425
426static int wanrouter_device_setup(struct wan_device *wandev,
427 wandev_conf_t __user *u_conf)
428{
429 void *data = NULL;
430 wandev_conf_t *conf;
431 int err = -EINVAL;
432
433 if (wandev->setup == NULL) { /* Nothing to do ? */
434 printk(KERN_INFO "%s: ERROR, No setup script: wandev->setup()\n",
435 wandev->name);
436 return 0;
437 }
438
439 conf = kmalloc(sizeof(wandev_conf_t), GFP_KERNEL);
440 if (conf == NULL){
441 printk(KERN_INFO "%s: ERROR, Failed to allocate kernel memory !\n",
442 wandev->name);
443 return -ENOBUFS;
444 }
445
446 if (copy_from_user(conf, u_conf, sizeof(wandev_conf_t))) {
447 printk(KERN_INFO "%s: Failed to copy user config data to kernel space!\n",
448 wandev->name);
449 kfree(conf);
450 return -EFAULT;
451 }
452
453 if (conf->magic != ROUTER_MAGIC) {
454 kfree(conf);
455 printk(KERN_INFO "%s: ERROR, Invalid MAGIC Number\n",
456 wandev->name);
457 return -EINVAL;
458 }
459
460 if (conf->data_size && conf->data) {
461 if (conf->data_size > 128000) {
462 printk(KERN_INFO
463 "%s: ERROR, Invalid firmware data size %i !\n",
464 wandev->name, conf->data_size);
465 kfree(conf);
466 return -EINVAL;
467 }
468
469 data = vmalloc(conf->data_size);
470 if (!data) {
471 printk(KERN_INFO
472 "%s: ERROR, Failed allocate kernel memory !\n",
473 wandev->name);
474 kfree(conf);
475 return -ENOBUFS;
476 }
477 if (!copy_from_user(data, conf->data, conf->data_size)) {
478 conf->data = data;
479 err = wandev->setup(wandev, conf);
480 } else {
481 printk(KERN_INFO
482 "%s: ERROR, Failed to copy from user data !\n",
483 wandev->name);
484 err = -EFAULT;
485 }
486 vfree(data);
487 } else {
488 printk(KERN_INFO
489 "%s: ERROR, No firmware found ! Firmware size = %i !\n",
490 wandev->name, conf->data_size);
491 }
492
493 kfree(conf);
494 return err;
495}
496
497/*
498 * Shutdown WAN device.
499 * o delete all not opened logical channels for this device
500 * o call driver's shutdown() entry point
501 */
502
503static int wanrouter_device_shutdown(struct wan_device *wandev)
504{
505 struct net_device *dev;
506 int err=0;
507
508 if (wandev->state == WAN_UNCONFIGURED)
509 return 0;
510
511 printk(KERN_INFO "\n%s: Shutting Down!\n",wandev->name);
512
513 for (dev = wandev->dev; dev;) {
514 err = wanrouter_delete_interface(wandev, dev->name);
515 if (err)
516 return err;
517 /* The above function deallocates the current dev
518 * structure. Therefore, we cannot use netdev_priv(dev)
519 * as the next element: wandev->dev points to the
520 * next element */
521 dev = wandev->dev;
522 }
523
524 if (wandev->ndev)
525 return -EBUSY; /* there are opened interfaces */
526
527 if (wandev->shutdown)
528 err=wandev->shutdown(wandev);
529
530 return err;
531}
532
533/*
534 * Get WAN device status & statistics.
535 */
536
537static int wanrouter_device_stat(struct wan_device *wandev,
538 wandev_stat_t __user *u_stat)
539{
540 wandev_stat_t stat;
541
542 memset(&stat, 0, sizeof(stat));
543
544 /* Ask device driver to update device statistics */
545 if ((wandev->state != WAN_UNCONFIGURED) && wandev->update)
546 wandev->update(wandev);
547
548 /* Fill out structure */
549 stat.ndev = wandev->ndev;
550 stat.state = wandev->state;
551
552 if (copy_to_user(u_stat, &stat, sizeof(stat)))
553 return -EFAULT;
554
555 return 0;
556}
557
558/*
559 * Create new WAN interface.
560 * o verify user address space
561 * o copy configuration data to kernel address space
562 * o allocate network interface data space
563 * o call driver's new_if() entry point
564 * o make sure there is no interface name conflict
565 * o register network interface
566 */
567
568static int wanrouter_device_new_if(struct wan_device *wandev,
569 wanif_conf_t __user *u_conf)
570{
571 wanif_conf_t *cnf;
572 struct net_device *dev = NULL;
573 int err;
574
575 if ((wandev->state == WAN_UNCONFIGURED) || (wandev->new_if == NULL))
576 return -ENODEV;
577
578 cnf = kmalloc(sizeof(wanif_conf_t), GFP_KERNEL);
579 if (!cnf)
580 return -ENOBUFS;
581
582 err = -EFAULT;
583 if (copy_from_user(cnf, u_conf, sizeof(wanif_conf_t)))
584 goto out;
585
586 err = -EINVAL;
587 if (cnf->magic != ROUTER_MAGIC)
588 goto out;
589
590 if (cnf->config_id == WANCONFIG_MPPP) {
591 printk(KERN_INFO "%s: Wanpipe Mulit-Port PPP support has not been compiled in!\n",
592 wandev->name);
593 err = -EPROTONOSUPPORT;
594 goto out;
595 } else {
596 err = wandev->new_if(wandev, dev, cnf);
597 }
598
599 if (!err) {
600 /* Register network interface. This will invoke init()
601 * function supplied by the driver. If device registered
602 * successfully, add it to the interface list.
603 */
604
605#ifdef WANDEBUG
606 printk(KERN_INFO "%s: registering interface %s...\n",
607 wanrouter_modname, dev->name);
608#endif
609
610 err = register_netdev(dev);
611 if (!err) {
612 struct net_device *slave = NULL;
613 unsigned long smp_flags=0;
614
615 lock_adapter_irq(&wandev->lock, &smp_flags);
616
617 if (wandev->dev == NULL) {
618 wandev->dev = dev;
619 } else {
620 for (slave=wandev->dev;
621 DEV_TO_SLAVE(slave);
622 slave = DEV_TO_SLAVE(slave))
623 DEV_TO_SLAVE(slave) = dev;
624 }
625 ++wandev->ndev;
626
627 unlock_adapter_irq(&wandev->lock, &smp_flags);
628 err = 0; /* done !!! */
629 goto out;
630 }
631 if (wandev->del_if)
632 wandev->del_if(wandev, dev);
633 free_netdev(dev);
634 }
635
636out:
637 kfree(cnf);
638 return err;
639}
640
641
642/*
643 * Delete WAN logical channel.
644 * o verify user address space
645 * o copy configuration data to kernel address space
646 */
647
648static int wanrouter_device_del_if(struct wan_device *wandev, char __user *u_name)
649{
650 char name[WAN_IFNAME_SZ + 1];
651 int err = 0;
652
653 if (wandev->state == WAN_UNCONFIGURED)
654 return -ENODEV;
655
656 memset(name, 0, sizeof(name));
657
658 if (copy_from_user(name, u_name, WAN_IFNAME_SZ))
659 return -EFAULT;
660
661 err = wanrouter_delete_interface(wandev, name);
662 if (err)
663 return err;
664
665 /* If last interface being deleted, shutdown card
666 * This helps with administration at leaf nodes
667 * (You can tell if the person at the other end of the phone
668 * has an interface configured) and avoids DoS vulnerabilities
669 * in binary driver files - this fixes a problem with the current
670 * Sangoma driver going into strange states when all the network
671 * interfaces are deleted and the link irrecoverably disconnected.
672 */
673
674 if (!wandev->ndev && wandev->shutdown)
675 err = wandev->shutdown(wandev);
676
677 return err;
678}
679
680/*
681 * Miscellaneous Functions
682 */
683
684/*
685 * Find WAN device by name.
686 * Return pointer to the WAN device data space or NULL if device not found.
687 */
688
689static struct wan_device *wanrouter_find_device(char *name)
690{
691 struct wan_device *wandev;
692
693 for (wandev = wanrouter_router_devlist;
694 wandev && strcmp(wandev->name, name);
695 wandev = wandev->next);
696 return wandev;
697}
698
699/*
700 * Delete WAN logical channel identified by its name.
701 * o find logical channel by its name
702 * o call driver's del_if() entry point
703 * o unregister network interface
704 * o unlink channel data space from linked list of channels
705 * o release channel data space
706 *
707 * Return: 0 success
708 * -ENODEV channel not found.
709 * -EBUSY interface is open
710 *
711 * Note: If (force != 0), then device will be destroyed even if interface
712 * associated with it is open. It's caller's responsibility to make
713 * sure that opened interfaces are not removed!
714 */
715
716static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
717{
718 struct net_device *dev = NULL, *prev = NULL;
719 unsigned long smp_flags=0;
720
721 lock_adapter_irq(&wandev->lock, &smp_flags);
722 dev = wandev->dev;
723 prev = NULL;
724 while (dev && strcmp(name, dev->name)) {
725 struct net_device **slave = netdev_priv(dev);
726 prev = dev;
727 dev = *slave;
728 }
729 unlock_adapter_irq(&wandev->lock, &smp_flags);
730
731 if (dev == NULL)
732 return -ENODEV; /* interface not found */
733
734 if (netif_running(dev))
735 return -EBUSY; /* interface in use */
736
737 if (wandev->del_if)
738 wandev->del_if(wandev, dev);
739
740 lock_adapter_irq(&wandev->lock, &smp_flags);
741 if (prev) {
742 struct net_device **prev_slave = netdev_priv(prev);
743 struct net_device **slave = netdev_priv(dev);
744
745 *prev_slave = *slave;
746 } else {
747 struct net_device **slave = netdev_priv(dev);
748 wandev->dev = *slave;
749 }
750 --wandev->ndev;
751 unlock_adapter_irq(&wandev->lock, &smp_flags);
752
753 printk(KERN_INFO "%s: unregistering '%s'\n", wandev->name, dev->name);
754
755 unregister_netdev(dev);
756
757 free_netdev(dev);
758
759 return 0;
760}
761
762static void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
763 __acquires(lock)
764{
765 spin_lock_irqsave(lock, *smp_flags);
766}
767
768
769static void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags)
770 __releases(lock)
771{
772 spin_unlock_irqrestore(lock, *smp_flags);
773}
774
775EXPORT_SYMBOL(register_wan_device);
776EXPORT_SYMBOL(unregister_wan_device);
777
778MODULE_LICENSE("GPL");
779
780/*
781 * End
782 */
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c
deleted file mode 100644
index c43612ee96bb..000000000000
--- a/net/wanrouter/wanproc.c
+++ /dev/null
@@ -1,380 +0,0 @@
1/*****************************************************************************
2* wanproc.c WAN Router Module. /proc filesystem interface.
3*
4* This module is completely hardware-independent and provides
5* access to the router using Linux /proc filesystem.
6*
7* Author: Gideon Hack
8*
9* Copyright: (c) 1995-1999 Sangoma Technologies Inc.
10*
11* This program is free software; you can redistribute it and/or
12* modify it under the terms of the GNU General Public License
13* as published by the Free Software Foundation; either version
14* 2 of the License, or (at your option) any later version.
15* ============================================================================
16* Jun 02, 1999 Gideon Hack Updates for Linux 2.2.X kernels.
17* Jun 29, 1997 Alan Cox Merged with 1.0.3 vendor code
18* Jan 29, 1997 Gene Kozin v1.0.1. Implemented /proc read routines
19* Jan 30, 1997 Alan Cox Hacked around for 2.1
20* Dec 13, 1996 Gene Kozin Initial version (based on Sangoma's WANPIPE)
21*****************************************************************************/
22
23#include <linux/init.h> /* __initfunc et al. */
24#include <linux/stddef.h> /* offsetof(), etc. */
25#include <linux/errno.h> /* return codes */
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/wanrouter.h> /* WAN router API definitions */
29#include <linux/seq_file.h>
30#include <linux/mutex.h>
31
32#include <net/net_namespace.h>
33#include <asm/io.h>
34
35#define PROC_STATS_FORMAT "%30s: %12lu\n"
36
37/****** Defines and Macros **************************************************/
38
39#define PROT_DECODE(prot) ((prot == WANCONFIG_FR) ? " FR" :\
40 (prot == WANCONFIG_X25) ? " X25" : \
41 (prot == WANCONFIG_PPP) ? " PPP" : \
42 (prot == WANCONFIG_CHDLC) ? " CHDLC": \
43 (prot == WANCONFIG_MPPP) ? " MPPP" : \
44 " Unknown" )
45
46/****** Function Prototypes *************************************************/
47
48#ifdef CONFIG_PROC_FS
49
50/* Miscellaneous */
51
52/*
53 * Structures for interfacing with the /proc filesystem.
54 * Router creates its own directory /proc/net/router with the following
55 * entries:
56 * config device configuration
57 * status global device statistics
58 * <device> entry for each WAN device
59 */
60
61/*
62 * Generic /proc/net/router/<file> file and inode operations
63 */
64
65/*
66 * /proc/net/router
67 */
68
69static DEFINE_MUTEX(config_mutex);
70static struct proc_dir_entry *proc_router;
71
72/* Strings */
73
74/*
75 * Interface functions
76 */
77
78/****** Proc filesystem entry points ****************************************/
79
80/*
81 * Iterator
82 */
83static void *r_start(struct seq_file *m, loff_t *pos)
84{
85 struct wan_device *wandev;
86 loff_t l = *pos;
87
88 mutex_lock(&config_mutex);
89 if (!l--)
90 return SEQ_START_TOKEN;
91 for (wandev = wanrouter_router_devlist; l-- && wandev;
92 wandev = wandev->next)
93 ;
94 return wandev;
95}
96
97static void *r_next(struct seq_file *m, void *v, loff_t *pos)
98{
99 struct wan_device *wandev = v;
100 (*pos)++;
101 return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next;
102}
103
104static void r_stop(struct seq_file *m, void *v)
105{
106 mutex_unlock(&config_mutex);
107}
108
109static int config_show(struct seq_file *m, void *v)
110{
111 struct wan_device *p = v;
112 if (v == SEQ_START_TOKEN) {
113 seq_puts(m, "Device name | port |IRQ|DMA| mem.addr |"
114 "mem.size|option1|option2|option3|option4\n");
115 return 0;
116 }
117 if (!p->state)
118 return 0;
119 seq_printf(m, "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
120 p->name, p->ioport, p->irq, p->dma, p->maddr, p->msize,
121 p->hw_opt[0], p->hw_opt[1], p->hw_opt[2], p->hw_opt[3]);
122 return 0;
123}
124
125static int status_show(struct seq_file *m, void *v)
126{
127 struct wan_device *p = v;
128 if (v == SEQ_START_TOKEN) {
129 seq_puts(m, "Device name |protocol|station|interface|"
130 "clocking|baud rate| MTU |ndev|link state\n");
131 return 0;
132 }
133 if (!p->state)
134 return 0;
135 seq_printf(m, "%-15s|%-8s| %-7s| %-9s|%-8s|%9u|%5u|%3u |",
136 p->name,
137 PROT_DECODE(p->config_id),
138 p->config_id == WANCONFIG_FR ?
139 (p->station ? "Node" : "CPE") :
140 (p->config_id == WANCONFIG_X25 ?
141 (p->station ? "DCE" : "DTE") :
142 ("N/A")),
143 p->interface ? "V.35" : "RS-232",
144 p->clocking ? "internal" : "external",
145 p->bps,
146 p->mtu,
147 p->ndev);
148
149 switch (p->state) {
150 case WAN_UNCONFIGURED:
151 seq_printf(m, "%-12s\n", "unconfigured");
152 break;
153 case WAN_DISCONNECTED:
154 seq_printf(m, "%-12s\n", "disconnected");
155 break;
156 case WAN_CONNECTING:
157 seq_printf(m, "%-12s\n", "connecting");
158 break;
159 case WAN_CONNECTED:
160 seq_printf(m, "%-12s\n", "connected");
161 break;
162 default:
163 seq_printf(m, "%-12s\n", "invalid");
164 break;
165 }
166 return 0;
167}
168
169static const struct seq_operations config_op = {
170 .start = r_start,
171 .next = r_next,
172 .stop = r_stop,
173 .show = config_show,
174};
175
176static const struct seq_operations status_op = {
177 .start = r_start,
178 .next = r_next,
179 .stop = r_stop,
180 .show = status_show,
181};
182
183static int config_open(struct inode *inode, struct file *file)
184{
185 return seq_open(file, &config_op);
186}
187
188static int status_open(struct inode *inode, struct file *file)
189{
190 return seq_open(file, &status_op);
191}
192
193static const struct file_operations config_fops = {
194 .owner = THIS_MODULE,
195 .open = config_open,
196 .read = seq_read,
197 .llseek = seq_lseek,
198 .release = seq_release,
199};
200
201static const struct file_operations status_fops = {
202 .owner = THIS_MODULE,
203 .open = status_open,
204 .read = seq_read,
205 .llseek = seq_lseek,
206 .release = seq_release,
207};
208
209static int wandev_show(struct seq_file *m, void *v)
210{
211 struct wan_device *wandev = m->private;
212
213 if (wandev->magic != ROUTER_MAGIC)
214 return 0;
215
216 if (!wandev->state) {
217 seq_puts(m, "device is not configured!\n");
218 return 0;
219 }
220
221 /* Update device statistics */
222 if (wandev->update) {
223 int err = wandev->update(wandev);
224 if (err == -EAGAIN) {
225 seq_puts(m, "Device is busy!\n");
226 return 0;
227 }
228 if (err) {
229 seq_puts(m, "Device is not configured!\n");
230 return 0;
231 }
232 }
233
234 seq_printf(m, PROC_STATS_FORMAT,
235 "total packets received", wandev->stats.rx_packets);
236 seq_printf(m, PROC_STATS_FORMAT,
237 "total packets transmitted", wandev->stats.tx_packets);
238 seq_printf(m, PROC_STATS_FORMAT,
239 "total bytes received", wandev->stats.rx_bytes);
240 seq_printf(m, PROC_STATS_FORMAT,
241 "total bytes transmitted", wandev->stats.tx_bytes);
242 seq_printf(m, PROC_STATS_FORMAT,
243 "bad packets received", wandev->stats.rx_errors);
244 seq_printf(m, PROC_STATS_FORMAT,
245 "packet transmit problems", wandev->stats.tx_errors);
246 seq_printf(m, PROC_STATS_FORMAT,
247 "received frames dropped", wandev->stats.rx_dropped);
248 seq_printf(m, PROC_STATS_FORMAT,
249 "transmit frames dropped", wandev->stats.tx_dropped);
250 seq_printf(m, PROC_STATS_FORMAT,
251 "multicast packets received", wandev->stats.multicast);
252 seq_printf(m, PROC_STATS_FORMAT,
253 "transmit collisions", wandev->stats.collisions);
254 seq_printf(m, PROC_STATS_FORMAT,
255 "receive length errors", wandev->stats.rx_length_errors);
256 seq_printf(m, PROC_STATS_FORMAT,
257 "receiver overrun errors", wandev->stats.rx_over_errors);
258 seq_printf(m, PROC_STATS_FORMAT,
259 "CRC errors", wandev->stats.rx_crc_errors);
260 seq_printf(m, PROC_STATS_FORMAT,
261 "frame format errors (aborts)", wandev->stats.rx_frame_errors);
262 seq_printf(m, PROC_STATS_FORMAT,
263 "receiver fifo overrun", wandev->stats.rx_fifo_errors);
264 seq_printf(m, PROC_STATS_FORMAT,
265 "receiver missed packet", wandev->stats.rx_missed_errors);
266 seq_printf(m, PROC_STATS_FORMAT,
267 "aborted frames transmitted", wandev->stats.tx_aborted_errors);
268 return 0;
269}
270
271static int wandev_open(struct inode *inode, struct file *file)
272{
273 return single_open(file, wandev_show, PDE(inode)->data);
274}
275
276static const struct file_operations wandev_fops = {
277 .owner = THIS_MODULE,
278 .open = wandev_open,
279 .read = seq_read,
280 .llseek = seq_lseek,
281 .release = single_release,
282 .unlocked_ioctl = wanrouter_ioctl,
283};
284
285/*
286 * Initialize router proc interface.
287 */
288
289int __init wanrouter_proc_init(void)
290{
291 struct proc_dir_entry *p;
292 proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net);
293 if (!proc_router)
294 goto fail;
295
296 p = proc_create("config", S_IRUGO, proc_router, &config_fops);
297 if (!p)
298 goto fail_config;
299 p = proc_create("status", S_IRUGO, proc_router, &status_fops);
300 if (!p)
301 goto fail_stat;
302 return 0;
303fail_stat:
304 remove_proc_entry("config", proc_router);
305fail_config:
306 remove_proc_entry(ROUTER_NAME, init_net.proc_net);
307fail:
308 return -ENOMEM;
309}
310
311/*
312 * Clean up router proc interface.
313 */
314
315void wanrouter_proc_cleanup(void)
316{
317 remove_proc_entry("config", proc_router);
318 remove_proc_entry("status", proc_router);
319 remove_proc_entry(ROUTER_NAME, init_net.proc_net);
320}
321
322/*
323 * Add directory entry for WAN device.
324 */
325
326int wanrouter_proc_add(struct wan_device* wandev)
327{
328 if (wandev->magic != ROUTER_MAGIC)
329 return -EINVAL;
330
331 wandev->dent = proc_create(wandev->name, S_IRUGO,
332 proc_router, &wandev_fops);
333 if (!wandev->dent)
334 return -ENOMEM;
335 wandev->dent->data = wandev;
336 return 0;
337}
338
339/*
340 * Delete directory entry for WAN device.
341 */
342int wanrouter_proc_delete(struct wan_device* wandev)
343{
344 if (wandev->magic != ROUTER_MAGIC)
345 return -EINVAL;
346 remove_proc_entry(wandev->name, proc_router);
347 return 0;
348}
349
350#else
351
352/*
353 * No /proc - output stubs
354 */
355
356int __init wanrouter_proc_init(void)
357{
358 return 0;
359}
360
361void wanrouter_proc_cleanup(void)
362{
363}
364
365int wanrouter_proc_add(struct wan_device *wandev)
366{
367 return 0;
368}
369
370int wanrouter_proc_delete(struct wan_device *wandev)
371{
372 return 0;
373}
374
375#endif
376
377/*
378 * End
379 */
380