aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/hamradio/mkiss.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/hamradio/mkiss.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/hamradio/mkiss.c')
-rw-r--r--drivers/net/hamradio/mkiss.c951
1 files changed, 951 insertions, 0 deletions
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
new file mode 100644
index 000000000000..d9ea080aea0f
--- /dev/null
+++ b/drivers/net/hamradio/mkiss.c
@@ -0,0 +1,951 @@
1/*
2 * MKISS Driver
3 *
4 * This module:
5 * This module is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 * This module implements the AX.25 protocol for kernel-based
11 * devices like TTYs. It interfaces between a raw TTY, and the
12 * kernel's AX.25 protocol layers, just like slip.c.
13 * AX.25 needs to be separated from slip.c while slip.c is no
14 * longer a static kernel device since it is a module.
15 * This method clears the way to implement other kiss protocols
16 * like mkiss smack g8bpq ..... so far only mkiss is implemented.
17 *
18 * Hans Alblas <hans@esrac.ele.tue.nl>
19 *
20 * History
21 * Jonathan (G4KLX) Fixed to match Linux networking changes - 2.1.15.
22 * Matthias (DG2FEF) Added support for FlexNet CRC (on special request)
23 * Fixed bug in ax25_close(): dev_lock_wait() was
24 * called twice, causing a deadlock.
25 * Jeroen (PE1RXQ) Removed old MKISS_MAGIC stuff and calls to
26 * MOD_*_USE_COUNT
27 * Remove cli() and fix rtnl lock usage.
28 */
29
30#include <linux/config.h>
31#include <linux/module.h>
32#include <asm/system.h>
33#include <linux/bitops.h>
34#include <asm/uaccess.h>
35#include <linux/string.h>
36#include <linux/mm.h>
37#include <linux/interrupt.h>
38#include <linux/in.h>
39#include <linux/inet.h>
40#include <linux/tty.h>
41#include <linux/errno.h>
42#include <linux/netdevice.h>
43#include <linux/major.h>
44#include <linux/init.h>
45#include <linux/rtnetlink.h>
46#include <linux/etherdevice.h>
47#include <linux/skbuff.h>
48#include <linux/if_arp.h>
49
50#include <net/ax25.h>
51
52#include "mkiss.h"
53
54#ifdef CONFIG_INET
55#include <linux/ip.h>
56#include <linux/tcp.h>
57#endif
58
59static char banner[] __initdata = KERN_INFO "mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
60
61typedef struct ax25_ctrl {
62 struct ax_disp ctrl; /* */
63 struct net_device dev; /* the device */
64} ax25_ctrl_t;
65
66static ax25_ctrl_t **ax25_ctrls;
67
68int ax25_maxdev = AX25_MAXDEV; /* Can be overridden with insmod! */
69
70static struct tty_ldisc ax_ldisc;
71
72static int ax25_init(struct net_device *);
73static int kiss_esc(unsigned char *, unsigned char *, int);
74static int kiss_esc_crc(unsigned char *, unsigned char *, unsigned short, int);
75static void kiss_unesc(struct ax_disp *, unsigned char);
76
77/*---------------------------------------------------------------------------*/
78
79static const unsigned short Crc_flex_table[] = {
80 0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38,
81 0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770,
82 0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9,
83 0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1,
84 0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a,
85 0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672,
86 0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb,
87 0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3,
88 0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c,
89 0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574,
90 0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd,
91 0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5,
92 0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e,
93 0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476,
94 0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf,
95 0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7,
96 0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30,
97 0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378,
98 0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1,
99 0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9,
100 0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32,
101 0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a,
102 0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3,
103 0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb,
104 0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34,
105 0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c,
106 0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5,
107 0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd,
108 0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36,
109 0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e,
110 0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7,
111 0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff
112};
113
114/*---------------------------------------------------------------------------*/
115
116static unsigned short calc_crc_flex(unsigned char *cp, int size)
117{
118 unsigned short crc = 0xffff;
119
120 while (size--)
121 crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
122
123 return crc;
124}
125
126/*---------------------------------------------------------------------------*/
127
128static int check_crc_flex(unsigned char *cp, int size)
129{
130 unsigned short crc = 0xffff;
131
132 if (size < 3)
133 return -1;
134
135 while (size--)
136 crc = (crc << 8) ^ Crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];
137
138 if ((crc & 0xffff) != 0x7070)
139 return -1;
140
141 return 0;
142}
143
144/*---------------------------------------------------------------------------*/
145
146/* Find a free channel, and link in this `tty' line. */
147static inline struct ax_disp *ax_alloc(void)
148{
149 ax25_ctrl_t *axp=NULL;
150 int i;
151
152 for (i = 0; i < ax25_maxdev; i++) {
153 axp = ax25_ctrls[i];
154
155 /* Not allocated ? */
156 if (axp == NULL)
157 break;
158
159 /* Not in use ? */
160 if (!test_and_set_bit(AXF_INUSE, &axp->ctrl.flags))
161 break;
162 }
163
164 /* Sorry, too many, all slots in use */
165 if (i >= ax25_maxdev)
166 return NULL;
167
168 /* If no channels are available, allocate one */
169 if (axp == NULL && (ax25_ctrls[i] = kmalloc(sizeof(ax25_ctrl_t), GFP_KERNEL)) != NULL) {
170 axp = ax25_ctrls[i];
171 }
172 memset(axp, 0, sizeof(ax25_ctrl_t));
173
174 /* Initialize channel control data */
175 set_bit(AXF_INUSE, &axp->ctrl.flags);
176 sprintf(axp->dev.name, "ax%d", i++);
177 axp->ctrl.tty = NULL;
178 axp->dev.base_addr = i;
179 axp->dev.priv = (void *)&axp->ctrl;
180 axp->dev.next = NULL;
181 axp->dev.init = ax25_init;
182
183 if (axp != NULL) {
184 /*
185 * register device so that it can be ifconfig'ed
186 * ax25_init() will be called as a side-effect
187 * SIDE-EFFECT WARNING: ax25_init() CLEARS axp->ctrl !
188 */
189 if (register_netdev(&axp->dev) == 0) {
190 /* (Re-)Set the INUSE bit. Very Important! */
191 set_bit(AXF_INUSE, &axp->ctrl.flags);
192 axp->ctrl.dev = &axp->dev;
193 axp->dev.priv = (void *) &axp->ctrl;
194
195 return &axp->ctrl;
196 } else {
197 clear_bit(AXF_INUSE,&axp->ctrl.flags);
198 printk(KERN_ERR "mkiss: ax_alloc() - register_netdev() failure.\n");
199 }
200 }
201
202 return NULL;
203}
204
205/* Free an AX25 channel. */
206static inline void ax_free(struct ax_disp *ax)
207{
208 /* Free all AX25 frame buffers. */
209 if (ax->rbuff)
210 kfree(ax->rbuff);
211 ax->rbuff = NULL;
212 if (ax->xbuff)
213 kfree(ax->xbuff);
214 ax->xbuff = NULL;
215 if (!test_and_clear_bit(AXF_INUSE, &ax->flags))
216 printk(KERN_ERR "mkiss: %s: ax_free for already free unit.\n", ax->dev->name);
217}
218
219static void ax_changedmtu(struct ax_disp *ax)
220{
221 struct net_device *dev = ax->dev;
222 unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
223 int len;
224
225 len = dev->mtu * 2;
226
227 /*
228 * allow for arrival of larger UDP packets, even if we say not to
229 * also fixes a bug in which SunOS sends 512-byte packets even with
230 * an MSS of 128
231 */
232 if (len < 576 * 2)
233 len = 576 * 2;
234
235 xbuff = kmalloc(len + 4, GFP_ATOMIC);
236 rbuff = kmalloc(len + 4, GFP_ATOMIC);
237
238 if (xbuff == NULL || rbuff == NULL) {
239 printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, MTU change cancelled.\n",
240 ax->dev->name);
241 dev->mtu = ax->mtu;
242 if (xbuff != NULL)
243 kfree(xbuff);
244 if (rbuff != NULL)
245 kfree(rbuff);
246 return;
247 }
248
249 spin_lock_bh(&ax->buflock);
250
251 oxbuff = ax->xbuff;
252 ax->xbuff = xbuff;
253 orbuff = ax->rbuff;
254 ax->rbuff = rbuff;
255
256 if (ax->xleft) {
257 if (ax->xleft <= len) {
258 memcpy(ax->xbuff, ax->xhead, ax->xleft);
259 } else {
260 ax->xleft = 0;
261 ax->tx_dropped++;
262 }
263 }
264
265 ax->xhead = ax->xbuff;
266
267 if (ax->rcount) {
268 if (ax->rcount <= len) {
269 memcpy(ax->rbuff, orbuff, ax->rcount);
270 } else {
271 ax->rcount = 0;
272 ax->rx_over_errors++;
273 set_bit(AXF_ERROR, &ax->flags);
274 }
275 }
276
277 ax->mtu = dev->mtu + 73;
278 ax->buffsize = len;
279
280 spin_unlock_bh(&ax->buflock);
281
282 if (oxbuff != NULL)
283 kfree(oxbuff);
284 if (orbuff != NULL)
285 kfree(orbuff);
286}
287
288
289/* Set the "sending" flag. This must be atomic. */
290static inline void ax_lock(struct ax_disp *ax)
291{
292 netif_stop_queue(ax->dev);
293}
294
295
296/* Clear the "sending" flag. This must be atomic. */
297static inline void ax_unlock(struct ax_disp *ax)
298{
299 netif_start_queue(ax->dev);
300}
301
302/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
303static void ax_bump(struct ax_disp *ax)
304{
305 struct sk_buff *skb;
306 int count;
307
308 spin_lock_bh(&ax->buflock);
309 if (ax->rbuff[0] > 0x0f) {
310 if (ax->rbuff[0] & 0x20) {
311 ax->crcmode = CRC_MODE_FLEX;
312 if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
313 ax->rx_errors++;
314 return;
315 }
316 ax->rcount -= 2;
317 /* dl9sau bugfix: the trailling two bytes flexnet crc
318 * will not be passed to the kernel. thus we have
319 * to correct the kissparm signature, because it
320 * indicates a crc but there's none
321 */
322 *ax->rbuff &= ~0x20;
323 }
324 }
325 spin_unlock_bh(&ax->buflock);
326
327 count = ax->rcount;
328
329 if ((skb = dev_alloc_skb(count)) == NULL) {
330 printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n", ax->dev->name);
331 ax->rx_dropped++;
332 return;
333 }
334
335 skb->dev = ax->dev;
336 spin_lock_bh(&ax->buflock);
337 memcpy(skb_put(skb,count), ax->rbuff, count);
338 spin_unlock_bh(&ax->buflock);
339 skb->mac.raw = skb->data;
340 skb->protocol = htons(ETH_P_AX25);
341 netif_rx(skb);
342 ax->dev->last_rx = jiffies;
343 ax->rx_packets++;
344 ax->rx_bytes+=count;
345}
346
347/* Encapsulate one AX.25 packet and stuff into a TTY queue. */
348static void ax_encaps(struct ax_disp *ax, unsigned char *icp, int len)
349{
350 unsigned char *p;
351 int actual, count;
352
353 if (ax->mtu != ax->dev->mtu + 73) /* Someone has been ifconfigging */
354 ax_changedmtu(ax);
355
356 if (len > ax->mtu) { /* Sigh, shouldn't occur BUT ... */
357 len = ax->mtu;
358 printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
359 ax->tx_dropped++;
360 ax_unlock(ax);
361 return;
362 }
363
364 p = icp;
365
366 spin_lock_bh(&ax->buflock);
367 switch (ax->crcmode) {
368 unsigned short crc;
369
370 case CRC_MODE_FLEX:
371 *p |= 0x20;
372 crc = calc_crc_flex(p, len);
373 count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
374 break;
375
376 default:
377 count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
378 break;
379 }
380
381 ax->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
382 actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
383 ax->tx_packets++;
384 ax->tx_bytes+=actual;
385 ax->dev->trans_start = jiffies;
386 ax->xleft = count - actual;
387 ax->xhead = ax->xbuff + actual;
388
389 spin_unlock_bh(&ax->buflock);
390}
391
392/*
393 * Called by the driver when there's room for more data. If we have
394 * more packets to send, we send them here.
395 */
396static void ax25_write_wakeup(struct tty_struct *tty)
397{
398 int actual;
399 struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
400
401 /* First make sure we're connected. */
402 if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev))
403 return;
404 if (ax->xleft <= 0) {
405 /* Now serial buffer is almost free & we can start
406 * transmission of another packet
407 */
408 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
409
410 netif_wake_queue(ax->dev);
411 return;
412 }
413
414 actual = tty->driver->write(tty, ax->xhead, ax->xleft);
415 ax->xleft -= actual;
416 ax->xhead += actual;
417}
418
419/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
420static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
421{
422 struct ax_disp *ax = netdev_priv(dev);
423
424 if (!netif_running(dev)) {
425 printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
426 return 1;
427 }
428
429 if (netif_queue_stopped(dev)) {
430 /*
431 * May be we must check transmitter timeout here ?
432 * 14 Oct 1994 Dmitry Gorodchanin.
433 */
434 if (jiffies - dev->trans_start < 20 * HZ) {
435 /* 20 sec timeout not reached */
436 return 1;
437 }
438
439 printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
440 (ax->tty->driver->chars_in_buffer(ax->tty) || ax->xleft) ?
441 "bad line quality" : "driver error");
442
443 ax->xleft = 0;
444 ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
445 ax_unlock(ax);
446 }
447
448 /* We were not busy, so we are now... :-) */
449 if (skb != NULL) {
450 ax_lock(ax);
451 ax_encaps(ax, skb->data, skb->len);
452 kfree_skb(skb);
453 }
454
455 return 0;
456}
457
458#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
459
460/* Return the frame type ID */
461static int ax_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
462 void *daddr, void *saddr, unsigned len)
463{
464#ifdef CONFIG_INET
465 if (type != htons(ETH_P_AX25))
466 return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
467#endif
468 return 0;
469}
470
471
472static int ax_rebuild_header(struct sk_buff *skb)
473{
474#ifdef CONFIG_INET
475 return ax25_rebuild_header(skb);
476#else
477 return 0;
478#endif
479}
480
481#endif /* CONFIG_{AX25,AX25_MODULE} */
482
483/* Open the low-level part of the AX25 channel. Easy! */
484static int ax_open(struct net_device *dev)
485{
486 struct ax_disp *ax = netdev_priv(dev);
487 unsigned long len;
488
489 if (ax->tty == NULL)
490 return -ENODEV;
491
492 /*
493 * Allocate the frame buffers:
494 *
495 * rbuff Receive buffer.
496 * xbuff Transmit buffer.
497 */
498 len = dev->mtu * 2;
499
500 /*
501 * allow for arrival of larger UDP packets, even if we say not to
502 * also fixes a bug in which SunOS sends 512-byte packets even with
503 * an MSS of 128
504 */
505 if (len < 576 * 2)
506 len = 576 * 2;
507
508 if ((ax->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
509 goto norbuff;
510
511 if ((ax->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
512 goto noxbuff;
513
514 ax->mtu = dev->mtu + 73;
515 ax->buffsize = len;
516 ax->rcount = 0;
517 ax->xleft = 0;
518
519 ax->flags &= (1 << AXF_INUSE); /* Clear ESCAPE & ERROR flags */
520
521 spin_lock_init(&ax->buflock);
522
523 netif_start_queue(dev);
524 return 0;
525
526noxbuff:
527 kfree(ax->rbuff);
528
529norbuff:
530 return -ENOMEM;
531}
532
533
534/* Close the low-level part of the AX25 channel. Easy! */
535static int ax_close(struct net_device *dev)
536{
537 struct ax_disp *ax = netdev_priv(dev);
538
539 if (ax->tty == NULL)
540 return -EBUSY;
541
542 ax->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
543
544 netif_stop_queue(dev);
545
546 return 0;
547}
548
549static int ax25_receive_room(struct tty_struct *tty)
550{
551 return 65536; /* We can handle an infinite amount of data. :-) */
552}
553
554/*
555 * Handle the 'receiver data ready' interrupt.
556 * This function is called by the 'tty_io' module in the kernel when
557 * a block of data has been received, which can now be decapsulated
558 * and sent on to the AX.25 layer for further processing.
559 */
560static void ax25_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
561{
562 struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
563
564 if (ax == NULL || ax->magic != AX25_MAGIC || !netif_running(ax->dev))
565 return;
566
567 /*
568 * Argh! mtu change time! - costs us the packet part received
569 * at the change
570 */
571 if (ax->mtu != ax->dev->mtu + 73)
572 ax_changedmtu(ax);
573
574 /* Read the characters out of the buffer */
575 while (count--) {
576 if (fp != NULL && *fp++) {
577 if (!test_and_set_bit(AXF_ERROR, &ax->flags))
578 ax->rx_errors++;
579 cp++;
580 continue;
581 }
582
583 kiss_unesc(ax, *cp++);
584 }
585}
586
587static int ax25_open(struct tty_struct *tty)
588{
589 struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
590 int err;
591
592 /* First make sure we're not already connected. */
593 if (ax && ax->magic == AX25_MAGIC)
594 return -EEXIST;
595
596 /* OK. Find a free AX25 channel to use. */
597 if ((ax = ax_alloc()) == NULL)
598 return -ENFILE;
599
600 ax->tty = tty;
601 tty->disc_data = ax;
602
603 if (tty->driver->flush_buffer)
604 tty->driver->flush_buffer(tty);
605
606 /* Restore default settings */
607 ax->dev->type = ARPHRD_AX25;
608
609 /* Perform the low-level AX25 initialization. */
610 if ((err = ax_open(ax->dev)))
611 return err;
612
613 /* Done. We have linked the TTY line to a channel. */
614 return ax->dev->base_addr;
615}
616
617static void ax25_close(struct tty_struct *tty)
618{
619 struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
620
621 /* First make sure we're connected. */
622 if (ax == NULL || ax->magic != AX25_MAGIC)
623 return;
624
625 unregister_netdev(ax->dev);
626
627 tty->disc_data = NULL;
628 ax->tty = NULL;
629
630 ax_free(ax);
631}
632
633
634static struct net_device_stats *ax_get_stats(struct net_device *dev)
635{
636 static struct net_device_stats stats;
637 struct ax_disp *ax = netdev_priv(dev);
638
639 memset(&stats, 0, sizeof(struct net_device_stats));
640
641 stats.rx_packets = ax->rx_packets;
642 stats.tx_packets = ax->tx_packets;
643 stats.rx_bytes = ax->rx_bytes;
644 stats.tx_bytes = ax->tx_bytes;
645 stats.rx_dropped = ax->rx_dropped;
646 stats.tx_dropped = ax->tx_dropped;
647 stats.tx_errors = ax->tx_errors;
648 stats.rx_errors = ax->rx_errors;
649 stats.rx_over_errors = ax->rx_over_errors;
650
651 return &stats;
652}
653
654
655/************************************************************************
656 * STANDARD ENCAPSULATION *
657 ************************************************************************/
658
659static int kiss_esc(unsigned char *s, unsigned char *d, int len)
660{
661 unsigned char *ptr = d;
662 unsigned char c;
663
664 /*
665 * Send an initial END character to flush out any
666 * data that may have accumulated in the receiver
667 * due to line noise.
668 */
669
670 *ptr++ = END;
671
672 while (len-- > 0) {
673 switch (c = *s++) {
674 case END:
675 *ptr++ = ESC;
676 *ptr++ = ESC_END;
677 break;
678 case ESC:
679 *ptr++ = ESC;
680 *ptr++ = ESC_ESC;
681 break;
682 default:
683 *ptr++ = c;
684 break;
685 }
686 }
687
688 *ptr++ = END;
689
690 return ptr - d;
691}
692
693/*
694 * MW:
695 * OK its ugly, but tell me a better solution without copying the
696 * packet to a temporary buffer :-)
697 */
698static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc, int len)
699{
700 unsigned char *ptr = d;
701 unsigned char c=0;
702
703 *ptr++ = END;
704 while (len > 0) {
705 if (len > 2)
706 c = *s++;
707 else if (len > 1)
708 c = crc >> 8;
709 else if (len > 0)
710 c = crc & 0xff;
711
712 len--;
713
714 switch (c) {
715 case END:
716 *ptr++ = ESC;
717 *ptr++ = ESC_END;
718 break;
719 case ESC:
720 *ptr++ = ESC;
721 *ptr++ = ESC_ESC;
722 break;
723 default:
724 *ptr++ = c;
725 break;
726 }
727 }
728 *ptr++ = END;
729 return ptr - d;
730}
731
732static void kiss_unesc(struct ax_disp *ax, unsigned char s)
733{
734 switch (s) {
735 case END:
736 /* drop keeptest bit = VSV */
737 if (test_bit(AXF_KEEPTEST, &ax->flags))
738 clear_bit(AXF_KEEPTEST, &ax->flags);
739
740 if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
741 ax_bump(ax);
742
743 clear_bit(AXF_ESCAPE, &ax->flags);
744 ax->rcount = 0;
745 return;
746
747 case ESC:
748 set_bit(AXF_ESCAPE, &ax->flags);
749 return;
750 case ESC_ESC:
751 if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
752 s = ESC;
753 break;
754 case ESC_END:
755 if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
756 s = END;
757 break;
758 }
759
760 spin_lock_bh(&ax->buflock);
761 if (!test_bit(AXF_ERROR, &ax->flags)) {
762 if (ax->rcount < ax->buffsize) {
763 ax->rbuff[ax->rcount++] = s;
764 spin_unlock_bh(&ax->buflock);
765 return;
766 }
767
768 ax->rx_over_errors++;
769 set_bit(AXF_ERROR, &ax->flags);
770 }
771 spin_unlock_bh(&ax->buflock);
772}
773
774
775static int ax_set_mac_address(struct net_device *dev, void __user *addr)
776{
777 if (copy_from_user(dev->dev_addr, addr, AX25_ADDR_LEN))
778 return -EFAULT;
779 return 0;
780}
781
782static int ax_set_dev_mac_address(struct net_device *dev, void *addr)
783{
784 struct sockaddr *sa = addr;
785
786 memcpy(dev->dev_addr, sa->sa_data, AX25_ADDR_LEN);
787
788 return 0;
789}
790
791
792/* Perform I/O control on an active ax25 channel. */
793static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void __user *arg)
794{
795 struct ax_disp *ax = (struct ax_disp *) tty->disc_data;
796 unsigned int tmp;
797
798 /* First make sure we're connected. */
799 if (ax == NULL || ax->magic != AX25_MAGIC)
800 return -EINVAL;
801
802 switch (cmd) {
803 case SIOCGIFNAME:
804 if (copy_to_user(arg, ax->dev->name, strlen(ax->dev->name) + 1))
805 return -EFAULT;
806 return 0;
807
808 case SIOCGIFENCAP:
809 return put_user(4, (int __user *)arg);
810
811 case SIOCSIFENCAP:
812 if (get_user(tmp, (int __user *)arg))
813 return -EFAULT;
814 ax->mode = tmp;
815 ax->dev->addr_len = AX25_ADDR_LEN; /* sizeof an AX.25 addr */
816 ax->dev->hard_header_len = AX25_KISS_HEADER_LEN + AX25_MAX_HEADER_LEN + 3;
817 ax->dev->type = ARPHRD_AX25;
818 return 0;
819
820 case SIOCSIFHWADDR:
821 return ax_set_mac_address(ax->dev, arg);
822
823 default:
824 return -ENOIOCTLCMD;
825 }
826}
827
828static int ax_open_dev(struct net_device *dev)
829{
830 struct ax_disp *ax = netdev_priv(dev);
831
832 if (ax->tty == NULL)
833 return -ENODEV;
834
835 return 0;
836}
837
838
839/* Initialize the driver. Called by network startup. */
840static int ax25_init(struct net_device *dev)
841{
842 struct ax_disp *ax = netdev_priv(dev);
843
844 static char ax25_bcast[AX25_ADDR_LEN] =
845 {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
846 static char ax25_test[AX25_ADDR_LEN] =
847 {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
848
849 if (ax == NULL) /* Allocation failed ?? */
850 return -ENODEV;
851
852 /* Set up the "AX25 Control Block". (And clear statistics) */
853 memset(ax, 0, sizeof (struct ax_disp));
854 ax->magic = AX25_MAGIC;
855 ax->dev = dev;
856
857 /* Finish setting up the DEVICE info. */
858 dev->mtu = AX_MTU;
859 dev->hard_start_xmit = ax_xmit;
860 dev->open = ax_open_dev;
861 dev->stop = ax_close;
862 dev->get_stats = ax_get_stats;
863 dev->set_mac_address = ax_set_dev_mac_address;
864 dev->hard_header_len = 0;
865 dev->addr_len = 0;
866 dev->type = ARPHRD_AX25;
867 dev->tx_queue_len = 10;
868 dev->hard_header = ax_header;
869 dev->rebuild_header = ax_rebuild_header;
870
871 memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
872 memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);
873
874 /* New-style flags. */
875 dev->flags = IFF_BROADCAST | IFF_MULTICAST;
876
877 return 0;
878}
879
880
881/* ******************************************************************** */
882/* * Init MKISS driver * */
883/* ******************************************************************** */
884
885static int __init mkiss_init_driver(void)
886{
887 int status;
888
889 printk(banner);
890
891 if (ax25_maxdev < 4)
892 ax25_maxdev = 4; /* Sanity */
893
894 if ((ax25_ctrls = kmalloc(sizeof(void *) * ax25_maxdev, GFP_KERNEL)) == NULL) {
895 printk(KERN_ERR "mkiss: Can't allocate ax25_ctrls[] array!\n");
896 return -ENOMEM;
897 }
898
899 /* Clear the pointer array, we allocate devices when we need them */
900 memset(ax25_ctrls, 0, sizeof(void*) * ax25_maxdev); /* Pointers */
901
902 /* Fill in our line protocol discipline, and register it */
903 ax_ldisc.magic = TTY_LDISC_MAGIC;
904 ax_ldisc.name = "mkiss";
905 ax_ldisc.open = ax25_open;
906 ax_ldisc.close = ax25_close;
907 ax_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
908 unsigned int, unsigned long))ax25_disp_ioctl;
909 ax_ldisc.receive_buf = ax25_receive_buf;
910 ax_ldisc.receive_room = ax25_receive_room;
911 ax_ldisc.write_wakeup = ax25_write_wakeup;
912
913 if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0) {
914 printk(KERN_ERR "mkiss: can't register line discipline (err = %d)\n", status);
915 kfree(ax25_ctrls);
916 }
917 return status;
918}
919
920static void __exit mkiss_exit_driver(void)
921{
922 int i;
923
924 for (i = 0; i < ax25_maxdev; i++) {
925 if (ax25_ctrls[i]) {
926 /*
927 * VSV = if dev->start==0, then device
928 * unregistered while close proc.
929 */
930 if (netif_running(&ax25_ctrls[i]->dev))
931 unregister_netdev(&ax25_ctrls[i]->dev);
932 kfree(ax25_ctrls[i]);
933 }
934 }
935
936 kfree(ax25_ctrls);
937 ax25_ctrls = NULL;
938
939 if ((i = tty_register_ldisc(N_AX25, NULL)))
940 printk(KERN_ERR "mkiss: can't unregister line discipline (err = %d)\n", i);
941}
942
943MODULE_AUTHOR("Hans Albas PE1AYX <hans@esrac.ele.tue.nl>");
944MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
945MODULE_PARM(ax25_maxdev, "i");
946MODULE_PARM_DESC(ax25_maxdev, "number of MKISS devices");
947MODULE_LICENSE("GPL");
948MODULE_ALIAS_LDISC(N_AX25);
949module_init(mkiss_init_driver);
950module_exit(mkiss_exit_driver);
951