aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/hamradio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 12:05:25 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2005-10-28 12:05:25 -0400
commite5dfa9282f3db461a896a6692b529e1823ba98c6 (patch)
tree574d23cebc57c657373b0e1b6692c047aba8dd6e /drivers/net/hamradio
parent5dd962494f76fb3ef1196cd420b5d6260d7a3766 (diff)
parentb2ab040db85835e54c7559533df7f85902617926 (diff)
Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
Diffstat (limited to 'drivers/net/hamradio')
-rw-r--r--drivers/net/hamradio/Kconfig1
-rw-r--r--drivers/net/hamradio/bpqether.c9
-rw-r--r--drivers/net/hamradio/mkiss.c182
-rw-r--r--drivers/net/hamradio/mkiss.h62
4 files changed, 153 insertions, 101 deletions
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index de087cd609d9..896aa02000d7 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -1,6 +1,7 @@
1config MKISS 1config MKISS
2 tristate "Serial port KISS driver" 2 tristate "Serial port KISS driver"
3 depends on AX25 3 depends on AX25
4 select CRC16
4 ---help--- 5 ---help---
5 KISS is a protocol used for the exchange of data between a computer 6 KISS is a protocol used for the exchange of data between a computer
6 and a Terminal Node Controller (a small embedded system commonly 7 and a Terminal Node Controller (a small embedded system commonly
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 1756f0ed54cc..cb43a9d28774 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -144,7 +144,7 @@ static inline struct net_device *bpq_get_ax25_dev(struct net_device *dev)
144{ 144{
145 struct bpqdev *bpq; 145 struct bpqdev *bpq;
146 146
147 list_for_each_entry(bpq, &bpq_devices, bpq_list) { 147 list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) {
148 if (bpq->ethdev == dev) 148 if (bpq->ethdev == dev)
149 return bpq->axdev; 149 return bpq->axdev;
150 } 150 }
@@ -399,7 +399,7 @@ static void *bpq_seq_start(struct seq_file *seq, loff_t *pos)
399 if (*pos == 0) 399 if (*pos == 0)
400 return SEQ_START_TOKEN; 400 return SEQ_START_TOKEN;
401 401
402 list_for_each_entry(bpqdev, &bpq_devices, bpq_list) { 402 list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
403 if (i == *pos) 403 if (i == *pos)
404 return bpqdev; 404 return bpqdev;
405 } 405 }
@@ -418,7 +418,7 @@ static void *bpq_seq_next(struct seq_file *seq, void *v, loff_t *pos)
418 p = ((struct bpqdev *)v)->bpq_list.next; 418 p = ((struct bpqdev *)v)->bpq_list.next;
419 419
420 return (p == &bpq_devices) ? NULL 420 return (p == &bpq_devices) ? NULL
421 : list_entry(p, struct bpqdev, bpq_list); 421 : rcu_dereference(list_entry(p, struct bpqdev, bpq_list));
422} 422}
423 423
424static void bpq_seq_stop(struct seq_file *seq, void *v) 424static void bpq_seq_stop(struct seq_file *seq, void *v)
@@ -561,8 +561,6 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
561 if (!dev_is_ethdev(dev)) 561 if (!dev_is_ethdev(dev))
562 return NOTIFY_DONE; 562 return NOTIFY_DONE;
563 563
564 rcu_read_lock();
565
566 switch (event) { 564 switch (event) {
567 case NETDEV_UP: /* new ethernet device -> new BPQ interface */ 565 case NETDEV_UP: /* new ethernet device -> new BPQ interface */
568 if (bpq_get_ax25_dev(dev) == NULL) 566 if (bpq_get_ax25_dev(dev) == NULL)
@@ -581,7 +579,6 @@ static int bpq_device_event(struct notifier_block *this,unsigned long event, voi
581 default: 579 default:
582 break; 580 break;
583 } 581 }
584 rcu_read_unlock();
585 582
586 return NOTIFY_DONE; 583 return NOTIFY_DONE;
587} 584}
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index d9fe64b46f4b..85d6dc005be0 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -14,13 +14,14 @@
14 * 14 *
15 * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl> 15 * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
16 * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org> 16 * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
17 * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas@x-berg.in-berlin.de>
17 */ 18 */
18
19#include <linux/config.h> 19#include <linux/config.h>
20#include <linux/module.h> 20#include <linux/module.h>
21#include <asm/system.h> 21#include <asm/system.h>
22#include <linux/bitops.h> 22#include <linux/bitops.h>
23#include <asm/uaccess.h> 23#include <asm/uaccess.h>
24#include <linux/crc16.h>
24#include <linux/string.h> 25#include <linux/string.h>
25#include <linux/mm.h> 26#include <linux/mm.h>
26#include <linux/interrupt.h> 27#include <linux/interrupt.h>
@@ -39,11 +40,6 @@
39 40
40#include <net/ax25.h> 41#include <net/ax25.h>
41 42
42#ifdef CONFIG_INET
43#include <linux/ip.h>
44#include <linux/tcp.h>
45#endif
46
47#define AX_MTU 236 43#define AX_MTU 236
48 44
49/* SLIP/KISS protocol characters. */ 45/* SLIP/KISS protocol characters. */
@@ -80,9 +76,13 @@ struct mkiss {
80 76
81 int mode; 77 int mode;
82 int crcmode; /* MW: for FlexNet, SMACK etc. */ 78 int crcmode; /* MW: for FlexNet, SMACK etc. */
83#define CRC_MODE_NONE 0 79 int crcauto; /* CRC auto mode */
84#define CRC_MODE_FLEX 1 80
85#define CRC_MODE_SMACK 2 81#define CRC_MODE_NONE 0
82#define CRC_MODE_FLEX 1
83#define CRC_MODE_SMACK 2
84#define CRC_MODE_FLEX_TEST 3
85#define CRC_MODE_SMACK_TEST 4
86 86
87 atomic_t refcnt; 87 atomic_t refcnt;
88 struct semaphore dead_sem; 88 struct semaphore dead_sem;
@@ -151,6 +151,21 @@ static int check_crc_flex(unsigned char *cp, int size)
151 return 0; 151 return 0;
152} 152}
153 153
154static int check_crc_16(unsigned char *cp, int size)
155{
156 unsigned short crc = 0x0000;
157
158 if (size < 3)
159 return -1;
160
161 crc = crc16(0, cp, size);
162
163 if (crc != 0x0000)
164 return -1;
165
166 return 0;
167}
168
154/* 169/*
155 * Standard encapsulation 170 * Standard encapsulation
156 */ 171 */
@@ -237,19 +252,42 @@ static void ax_bump(struct mkiss *ax)
237 252
238 spin_lock_bh(&ax->buflock); 253 spin_lock_bh(&ax->buflock);
239 if (ax->rbuff[0] > 0x0f) { 254 if (ax->rbuff[0] > 0x0f) {
240 if (ax->rbuff[0] & 0x20) { 255 if (ax->rbuff[0] & 0x80) {
241 ax->crcmode = CRC_MODE_FLEX; 256 if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
257 ax->stats.rx_errors++;
258 spin_unlock_bh(&ax->buflock);
259
260 return;
261 }
262 if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
263 printk(KERN_INFO
264 "mkiss: %s: Switchting to crc-smack\n",
265 ax->dev->name);
266 ax->crcmode = CRC_MODE_SMACK;
267 }
268 ax->rcount -= 2;
269 *ax->rbuff &= ~0x80;
270 } else if (ax->rbuff[0] & 0x20) {
242 if (check_crc_flex(ax->rbuff, ax->rcount) < 0) { 271 if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
243 ax->stats.rx_errors++; 272 ax->stats.rx_errors++;
273 spin_unlock_bh(&ax->buflock);
244 return; 274 return;
245 } 275 }
276 if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
277 printk(KERN_INFO
278 "mkiss: %s: Switchting to crc-flexnet\n",
279 ax->dev->name);
280 ax->crcmode = CRC_MODE_FLEX;
281 }
246 ax->rcount -= 2; 282 ax->rcount -= 2;
247 /* dl9sau bugfix: the trailling two bytes flexnet crc 283
248 * will not be passed to the kernel. thus we have 284 /*
249 * to correct the kissparm signature, because it 285 * dl9sau bugfix: the trailling two bytes flexnet crc
250 * indicates a crc but there's none 286 * will not be passed to the kernel. thus we have to
287 * correct the kissparm signature, because it indicates
288 * a crc but there's none
251 */ 289 */
252 *ax->rbuff &= ~0x20; 290 *ax->rbuff &= ~0x20;
253 } 291 }
254 } 292 }
255 spin_unlock_bh(&ax->buflock); 293 spin_unlock_bh(&ax->buflock);
@@ -417,20 +455,69 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
417 p = icp; 455 p = icp;
418 456
419 spin_lock_bh(&ax->buflock); 457 spin_lock_bh(&ax->buflock);
420 switch (ax->crcmode) { 458 if ((*p & 0x0f) != 0) {
421 unsigned short crc; 459 /* Configuration Command (kissparms(1).
460 * Protocol spec says: never append CRC.
461 * This fixes a very old bug in the linux
462 * kiss driver. -- dl9sau */
463 switch (*p & 0xff) {
464 case 0x85:
465 /* command from userspace especially for us,
466 * not for delivery to the tnc */
467 if (len > 1) {
468 int cmd = (p[1] & 0xff);
469 switch(cmd) {
470 case 3:
471 ax->crcmode = CRC_MODE_SMACK;
472 break;
473 case 2:
474 ax->crcmode = CRC_MODE_FLEX;
475 break;
476 case 1:
477 ax->crcmode = CRC_MODE_NONE;
478 break;
479 case 0:
480 default:
481 ax->crcmode = CRC_MODE_SMACK_TEST;
482 cmd = 0;
483 }
484 ax->crcauto = (cmd ? 0 : 1);
485 printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
486 }
487 spin_unlock_bh(&ax->buflock);
488 netif_start_queue(dev);
422 489
423 case CRC_MODE_FLEX: 490 return;
424 *p |= 0x20; 491 default:
425 crc = calc_crc_flex(p, len); 492 count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
426 count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2); 493 }
427 break; 494 } else {
495 unsigned short crc;
496 switch (ax->crcmode) {
497 case CRC_MODE_SMACK_TEST:
498 ax->crcmode = CRC_MODE_FLEX_TEST;
499 printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
500 // fall through
501 case CRC_MODE_SMACK:
502 *p |= 0x80;
503 crc = swab16(crc16(0, p, len));
504 count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
505 break;
506 case CRC_MODE_FLEX_TEST:
507 ax->crcmode = CRC_MODE_NONE;
508 printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
509 // fall through
510 case CRC_MODE_FLEX:
511 *p |= 0x20;
512 crc = calc_crc_flex(p, len);
513 count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
514 break;
515
516 default:
517 count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
518 }
519 }
428 520
429 default:
430 count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
431 break;
432 }
433
434 set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags); 521 set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
435 actual = ax->tty->driver->write(ax->tty, ax->xbuff, count); 522 actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
436 ax->stats.tx_packets++; 523 ax->stats.tx_packets++;
@@ -439,8 +526,6 @@ static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
439 ax->dev->trans_start = jiffies; 526 ax->dev->trans_start = jiffies;
440 ax->xleft = count - actual; 527 ax->xleft = count - actual;
441 ax->xhead = ax->xbuff + actual; 528 ax->xhead = ax->xbuff + actual;
442
443 spin_unlock_bh(&ax->buflock);
444} 529}
445 530
446/* Encapsulate an AX.25 packet and kick it into a TTY queue. */ 531/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
@@ -622,7 +707,7 @@ static void ax_setup(struct net_device *dev)
622 * best way to fix this is to use a rwlock in the tty struct, but for now we 707 * best way to fix this is to use a rwlock in the tty struct, but for now we
623 * use a single global rwlock for all ttys in ppp line discipline. 708 * use a single global rwlock for all ttys in ppp line discipline.
624 */ 709 */
625static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED; 710static DEFINE_RWLOCK(disc_data_lock);
626 711
627static struct mkiss *mkiss_get(struct tty_struct *tty) 712static struct mkiss *mkiss_get(struct tty_struct *tty)
628{ 713{
@@ -643,6 +728,8 @@ static void mkiss_put(struct mkiss *ax)
643 up(&ax->dead_sem); 728 up(&ax->dead_sem);
644} 729}
645 730
731static int crc_force = 0; /* Can be overridden with insmod */
732
646static int mkiss_open(struct tty_struct *tty) 733static int mkiss_open(struct tty_struct *tty)
647{ 734{
648 struct net_device *dev; 735 struct net_device *dev;
@@ -682,6 +769,33 @@ static int mkiss_open(struct tty_struct *tty)
682 if (register_netdev(dev)) 769 if (register_netdev(dev))
683 goto out_free_buffers; 770 goto out_free_buffers;
684 771
772 /* after register_netdev() - because else printk smashes the kernel */
773 switch (crc_force) {
774 case 3:
775 ax->crcmode = CRC_MODE_SMACK;
776 printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
777 ax->dev->name);
778 break;
779 case 2:
780 ax->crcmode = CRC_MODE_FLEX;
781 printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
782 ax->dev->name);
783 break;
784 case 1:
785 ax->crcmode = CRC_MODE_NONE;
786 printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
787 ax->dev->name);
788 break;
789 case 0:
790 /* fall through */
791 default:
792 crc_force = 0;
793 printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
794 ax->dev->name);
795 ax->crcmode = CRC_MODE_SMACK_TEST;
796 }
797 ax->crcauto = (crc_force ? 0 : 1);
798
685 netif_start_queue(dev); 799 netif_start_queue(dev);
686 800
687 /* Done. We have linked the TTY line to a channel. */ 801 /* Done. We have linked the TTY line to a channel. */
@@ -765,7 +879,6 @@ static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
765 879
766 case SIOCSIFHWADDR: { 880 case SIOCSIFHWADDR: {
767 char addr[AX25_ADDR_LEN]; 881 char addr[AX25_ADDR_LEN];
768printk(KERN_INFO "In SIOCSIFHWADDR");
769 882
770 if (copy_from_user(&addr, 883 if (copy_from_user(&addr,
771 (void __user *) arg, AX25_ADDR_LEN)) { 884 (void __user *) arg, AX25_ADDR_LEN)) {
@@ -864,6 +977,7 @@ out:
864} 977}
865 978
866static struct tty_ldisc ax_ldisc = { 979static struct tty_ldisc ax_ldisc = {
980 .owner = THIS_MODULE,
867 .magic = TTY_LDISC_MAGIC, 981 .magic = TTY_LDISC_MAGIC,
868 .name = "mkiss", 982 .name = "mkiss",
869 .open = mkiss_open, 983 .open = mkiss_open,
@@ -904,6 +1018,8 @@ static void __exit mkiss_exit_driver(void)
904 1018
905MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>"); 1019MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
906MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs"); 1020MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
1021MODULE_PARM(crc_force, "i");
1022MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
907MODULE_LICENSE("GPL"); 1023MODULE_LICENSE("GPL");
908MODULE_ALIAS_LDISC(N_AX25); 1024MODULE_ALIAS_LDISC(N_AX25);
909 1025
diff --git a/drivers/net/hamradio/mkiss.h b/drivers/net/hamradio/mkiss.h
deleted file mode 100644
index 4ab700478598..000000000000
--- a/drivers/net/hamradio/mkiss.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/****************************************************************************
2 * Defines for the Multi-KISS driver.
3 ****************************************************************************/
4
5#define AX25_MAXDEV 16 /* MAX number of AX25 channels;
6 This can be overridden with
7 insmod -oax25_maxdev=nnn */
8#define AX_MTU 236
9
10/* SLIP/KISS protocol characters. */
11#define END 0300 /* indicates end of frame */
12#define ESC 0333 /* indicates byte stuffing */
13#define ESC_END 0334 /* ESC ESC_END means END 'data' */
14#define ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */
15
16struct ax_disp {
17 int magic;
18
19 /* Various fields. */
20 struct tty_struct *tty; /* ptr to TTY structure */
21 struct net_device *dev; /* easy for intr handling */
22
23 /* These are pointers to the malloc()ed frame buffers. */
24 unsigned char *rbuff; /* receiver buffer */
25 int rcount; /* received chars counter */
26 unsigned char *xbuff; /* transmitter buffer */
27 unsigned char *xhead; /* pointer to next byte to XMIT */
28 int xleft; /* bytes left in XMIT queue */
29
30 /* SLIP interface statistics. */
31 unsigned long rx_packets; /* inbound frames counter */
32 unsigned long tx_packets; /* outbound frames counter */
33 unsigned long rx_bytes; /* inbound bytes counter */
34 unsigned long tx_bytes; /* outbound bytes counter */
35 unsigned long rx_errors; /* Parity, etc. errors */
36 unsigned long tx_errors; /* Planned stuff */
37 unsigned long rx_dropped; /* No memory for skb */
38 unsigned long tx_dropped; /* When MTU change */
39 unsigned long rx_over_errors; /* Frame bigger then SLIP buf. */
40
41 /* Detailed SLIP statistics. */
42 int mtu; /* Our mtu (to spot changes!) */
43 int buffsize; /* Max buffers sizes */
44
45
46 unsigned long flags; /* Flag values/ mode etc */
47 /* long req'd: used by set_bit --RR */
48#define AXF_INUSE 0 /* Channel in use */
49#define AXF_ESCAPE 1 /* ESC received */
50#define AXF_ERROR 2 /* Parity, etc. error */
51#define AXF_KEEPTEST 3 /* Keepalive test flag */
52#define AXF_OUTWAIT 4 /* is outpacket was flag */
53
54 int mode;
55 int crcmode; /* MW: for FlexNet, SMACK etc. */
56#define CRC_MODE_NONE 0
57#define CRC_MODE_FLEX 1
58#define CRC_MODE_SMACK 2
59 spinlock_t buflock; /* lock for rbuf and xbuf */
60};
61
62#define AX25_MAGIC 0x5316