vserver 1.9.5.x5
[linux-2.6.git] / drivers / net / hamradio / 6pack.c
1 /*
2  * 6pack.c      This module implements the 6pack protocol for kernel-based
3  *              devices like TTY. It interfaces between a raw TTY and the
4  *              kernel's AX.25 protocol layers.
5  *
6  * Authors:     Andreas Könsgen <ajk@iehk.rwth-aachen.de>
7  *              Ralf Baechle DL5RB <ralf@linux-mips.org>
8  *
9  * Quite a lot of stuff "stolen" by Joerg Reuter from slip.c, written by
10  *
11  *              Laurence Culhane, <loz@holmes.demon.co.uk>
12  *              Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
13  */
14
15 #include <linux/config.h>
16 #include <linux/module.h>
17 #include <asm/system.h>
18 #include <asm/uaccess.h>
19 #include <linux/bitops.h>
20 #include <linux/string.h>
21 #include <linux/mm.h>
22 #include <linux/interrupt.h>
23 #include <linux/in.h>
24 #include <linux/tty.h>
25 #include <linux/errno.h>
26 #include <linux/netdevice.h>
27 #include <linux/timer.h>
28 #include <net/ax25.h>
29 #include <linux/etherdevice.h>
30 #include <linux/skbuff.h>
31 #include <linux/rtnetlink.h>
32 #include <linux/spinlock.h>
33 #include <linux/if_arp.h>
34 #include <linux/init.h>
35 #include <linux/ip.h>
36 #include <linux/tcp.h>
37 #include <asm/semaphore.h>
38 #include <asm/atomic.h>
39
40 #define SIXPACK_VERSION    "Revision: 0.3.0"
41
42 /* sixpack priority commands */
43 #define SIXP_SEOF               0x40    /* start and end of a 6pack frame */
44 #define SIXP_TX_URUN            0x48    /* transmit overrun */
45 #define SIXP_RX_ORUN            0x50    /* receive overrun */
46 #define SIXP_RX_BUF_OVL         0x58    /* receive buffer overflow */
47
48 #define SIXP_CHKSUM             0xFF    /* valid checksum of a 6pack frame */
49
50 /* masks to get certain bits out of the status bytes sent by the TNC */
51
52 #define SIXP_CMD_MASK           0xC0
53 #define SIXP_CHN_MASK           0x07
54 #define SIXP_PRIO_CMD_MASK      0x80
55 #define SIXP_STD_CMD_MASK       0x40
56 #define SIXP_PRIO_DATA_MASK     0x38
57 #define SIXP_TX_MASK            0x20
58 #define SIXP_RX_MASK            0x10
59 #define SIXP_RX_DCD_MASK        0x18
60 #define SIXP_LEDS_ON            0x78
61 #define SIXP_LEDS_OFF           0x60
62 #define SIXP_CON                0x08
63 #define SIXP_STA                0x10
64
65 #define SIXP_FOUND_TNC          0xe9
66 #define SIXP_CON_ON             0x68
67 #define SIXP_DCD_MASK           0x08
68 #define SIXP_DAMA_OFF           0
69
70 /* default level 2 parameters */
71 #define SIXP_TXDELAY                    (HZ/4)  /* in 1 s */
72 #define SIXP_PERSIST                    50      /* in 256ths */
73 #define SIXP_SLOTTIME                   (HZ/10) /* in 1 s */
74 #define SIXP_INIT_RESYNC_TIMEOUT        (3*HZ/2) /* in 1 s */
75 #define SIXP_RESYNC_TIMEOUT             5*HZ    /* in 1 s */
76
77 /* 6pack configuration. */
78 #define SIXP_NRUNIT                     31      /* MAX number of 6pack channels */
79 #define SIXP_MTU                        256     /* Default MTU */
80
81 enum sixpack_flags {
82         SIXPF_ERROR,    /* Parity, etc. error   */
83 };
84
85 struct sixpack {
86         /* Various fields. */
87         struct tty_struct       *tty;           /* ptr to TTY structure */
88         struct net_device       *dev;           /* easy for intr handling  */
89
90         /* These are pointers to the malloc()ed frame buffers. */
91         unsigned char           *rbuff;         /* receiver buffer      */
92         int                     rcount;         /* received chars counter  */
93         unsigned char           *xbuff;         /* transmitter buffer   */
94         unsigned char           *xhead;         /* next byte to XMIT */
95         int                     xleft;          /* bytes left in XMIT queue  */
96
97         unsigned char           raw_buf[4];
98         unsigned char           cooked_buf[400];
99
100         unsigned int            rx_count;
101         unsigned int            rx_count_cooked;
102
103         /* 6pack interface statistics. */
104         struct net_device_stats stats;
105
106         int                     mtu;            /* Our mtu (to spot changes!) */
107         int                     buffsize;       /* Max buffers sizes */
108
109         unsigned long           flags;          /* Flag values/ mode etc */
110         unsigned char           mode;           /* 6pack mode */
111
112         /* 6pack stuff */
113         unsigned char           tx_delay;
114         unsigned char           persistence;
115         unsigned char           slottime;
116         unsigned char           duplex;
117         unsigned char           led_state;
118         unsigned char           status;
119         unsigned char           status1;
120         unsigned char           status2;
121         unsigned char           tx_enable;
122         unsigned char           tnc_state;
123
124         struct timer_list       tx_t;
125         struct timer_list       resync_t;
126         atomic_t                refcnt;
127         struct semaphore        dead_sem;
128         spinlock_t              lock;
129 };
130
131 #define AX25_6PACK_HEADER_LEN 0
132
133 static void sp_start_tx_timer(struct sixpack *);
134 static void sixpack_decode(struct sixpack *, unsigned char[], int);
135 static int encode_sixpack(unsigned char *, unsigned char *, int, unsigned char);
136
137 /*
138  * perform the persistence/slottime algorithm for CSMA access. If the
139  * persistence check was successful, write the data to the serial driver.
140  * Note that in case of DAMA operation, the data is not sent here.
141  */
142
143 static void sp_xmit_on_air(unsigned long channel)
144 {
145         struct sixpack *sp = (struct sixpack *) channel;
146         int actual;
147         static unsigned char random;
148
149         random = random * 17 + 41;
150
151         if (((sp->status1 & SIXP_DCD_MASK) == 0) && (random < sp->persistence)) {
152                 sp->led_state = 0x70;
153                 sp->tty->driver->write(sp->tty, &sp->led_state, 1);
154                 sp->tx_enable = 1;
155                 actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
156                 sp->xleft -= actual;
157                 sp->xhead += actual;
158                 sp->led_state = 0x60;
159                 sp->tty->driver->write(sp->tty, &sp->led_state, 1);
160                 sp->status2 = 0;
161         } else
162                 sp_start_tx_timer(sp);
163 }
164
165 /* ----> 6pack timer interrupt handler and friends. <---- */
166 static void sp_start_tx_timer(struct sixpack *sp)
167 {
168         int when = sp->slottime;
169
170         del_timer(&sp->tx_t);
171         sp->tx_t.data = (unsigned long) sp;
172         sp->tx_t.function = sp_xmit_on_air;
173         sp->tx_t.expires = jiffies + ((when + 1) * HZ) / 100;
174         add_timer(&sp->tx_t);
175 }
176
177 /* Encapsulate one AX.25 frame and stuff into a TTY queue. */
178 static void sp_encaps(struct sixpack *sp, unsigned char *icp, int len)
179 {
180         unsigned char *msg, *p = icp;
181         int actual, count;
182
183         if (len > sp->mtu) {    /* sp->mtu = AX25_MTU = max. PACLEN = 256 */
184                 msg = "oversized transmit packet!";
185                 goto out_drop;
186         }
187
188         if (len > sp->mtu) {    /* sp->mtu = AX25_MTU = max. PACLEN = 256 */
189                 msg = "oversized transmit packet!";
190                 goto out_drop;
191         }
192
193         if (p[0] > 5) {
194                 msg = "invalid KISS command";
195                 goto out_drop;
196         }
197
198         if ((p[0] != 0) && (len > 2)) {
199                 msg = "KISS control packet too long";
200                 goto out_drop;
201         }
202
203         if ((p[0] == 0) && (len < 15)) {
204                 msg = "bad AX.25 packet to transmit";
205                 goto out_drop;
206         }
207
208         count = encode_sixpack(p, sp->xbuff, len, sp->tx_delay);
209         set_bit(TTY_DO_WRITE_WAKEUP, &sp->tty->flags);
210
211         switch (p[0]) {
212         case 1: sp->tx_delay = p[1];
213                 return;
214         case 2: sp->persistence = p[1];
215                 return;
216         case 3: sp->slottime = p[1];
217                 return;
218         case 4: /* ignored */
219                 return;
220         case 5: sp->duplex = p[1];
221                 return;
222         }
223
224         if (p[0] != 0)
225                 return;
226
227         /*
228          * In case of fullduplex or DAMA operation, we don't take care about the
229          * state of the DCD or of any timers, as the determination of the
230          * correct time to send is the job of the AX.25 layer. We send
231          * immediately after data has arrived.
232          */
233         if (sp->duplex == 1) {
234                 sp->led_state = 0x70;
235                 sp->tty->driver->write(sp->tty, &sp->led_state, 1);
236                 sp->tx_enable = 1;
237                 actual = sp->tty->driver->write(sp->tty, sp->xbuff, count);
238                 sp->xleft = count - actual;
239                 sp->xhead = sp->xbuff + actual;
240                 sp->led_state = 0x60;
241                 sp->tty->driver->write(sp->tty, &sp->led_state, 1);
242         } else {
243                 sp->xleft = count;
244                 sp->xhead = sp->xbuff;
245                 sp->status2 = count;
246                 if (sp->duplex == 0)
247                         sp_start_tx_timer(sp);
248         }
249
250         return;
251
252 out_drop:
253         sp->stats.tx_dropped++;
254         netif_start_queue(sp->dev);
255         if (net_ratelimit())
256                 printk(KERN_DEBUG "%s: %s - dropped.\n", sp->dev->name, msg);
257 }
258
259 /* Encapsulate an IP datagram and kick it into a TTY queue. */
260
261 static int sp_xmit(struct sk_buff *skb, struct net_device *dev)
262 {
263         struct sixpack *sp = netdev_priv(dev);
264
265         spin_lock_bh(&sp->lock);
266         /* We were not busy, so we are now... :-) */
267         netif_stop_queue(dev);
268         sp->stats.tx_bytes += skb->len;
269         sp_encaps(sp, skb->data, skb->len);
270         spin_unlock_bh(&sp->lock);
271
272         dev_kfree_skb(skb);
273
274         return 0;
275 }
276
277 static int sp_open_dev(struct net_device *dev)
278 {
279         struct sixpack *sp = netdev_priv(dev);
280
281         if (sp->tty == NULL)
282                 return -ENODEV;
283         return 0;
284 }
285
286 /* Close the low-level part of the 6pack channel. */
287 static int sp_close(struct net_device *dev)
288 {
289         struct sixpack *sp = netdev_priv(dev);
290
291         spin_lock_bh(&sp->lock);
292         if (sp->tty) {
293                 /* TTY discipline is running. */
294                 clear_bit(TTY_DO_WRITE_WAKEUP, &sp->tty->flags);
295         }
296         netif_stop_queue(dev);
297         spin_unlock_bh(&sp->lock);
298
299         return 0;
300 }
301
302 /* Return the frame type ID */
303 static int sp_header(struct sk_buff *skb, struct net_device *dev,
304         unsigned short type, void *daddr, void *saddr, unsigned len)
305 {
306 #ifdef CONFIG_INET
307         if (type != htons(ETH_P_AX25))
308                 return ax25_encapsulate(skb, dev, type, daddr, saddr, len);
309 #endif
310         return 0;
311 }
312
313 static struct net_device_stats *sp_get_stats(struct net_device *dev)
314 {
315         struct sixpack *sp = netdev_priv(dev);
316         return &sp->stats;
317 }
318
319 static int sp_set_mac_address(struct net_device *dev, void *addr)
320 {
321         struct sockaddr_ax25 *sa = addr;
322
323         if (sa->sax25_family != AF_AX25)
324                 return -EINVAL;
325
326         if (!sa->sax25_ndigis)
327                 return -EINVAL;
328
329         spin_lock_irq(&dev->xmit_lock);
330         memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
331         spin_unlock_irq(&dev->xmit_lock);
332
333         return 0;
334 }
335
336 static int sp_rebuild_header(struct sk_buff *skb)
337 {
338 #ifdef CONFIG_INET
339         return ax25_rebuild_header(skb);
340 #else
341         return 0;
342 #endif
343 }
344
345 static void sp_setup(struct net_device *dev)
346 {
347         static char ax25_bcast[AX25_ADDR_LEN] =
348                 {'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
349         static char ax25_test[AX25_ADDR_LEN] =
350                 {'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
351
352         /* Finish setting up the DEVICE info. */
353         dev->mtu                = SIXP_MTU;
354         dev->hard_start_xmit    = sp_xmit;
355         dev->open               = sp_open_dev;
356         dev->destructor         = free_netdev;
357         dev->stop               = sp_close;
358         dev->hard_header        = sp_header;
359         dev->get_stats          = sp_get_stats;
360         dev->set_mac_address    = sp_set_mac_address;
361         dev->hard_header_len    = AX25_MAX_HEADER_LEN;
362         dev->addr_len           = AX25_ADDR_LEN;
363         dev->type               = ARPHRD_AX25;
364         dev->tx_queue_len       = 10;
365         dev->rebuild_header     = sp_rebuild_header;
366         dev->tx_timeout         = NULL;
367
368         /* Only activated in AX.25 mode */
369         memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
370         memcpy(dev->dev_addr, ax25_test, AX25_ADDR_LEN);
371
372         SET_MODULE_OWNER(dev);
373
374         dev->flags              = 0;
375 }
376
377 /* Send one completely decapsulated IP datagram to the IP layer. */
378
379 /*
380  * This is the routine that sends the received data to the kernel AX.25.
381  * 'cmd' is the KISS command. For AX.25 data, it is zero.
382  */
383
384 static void sp_bump(struct sixpack *sp, char cmd)
385 {
386         struct sk_buff *skb;
387         int count;
388         unsigned char *ptr;
389
390         count = sp->rcount + 1;
391
392         sp->stats.rx_bytes += count;
393
394         if ((skb = dev_alloc_skb(count)) == NULL)
395                 goto out_mem;
396
397         skb->dev = sp->dev;
398         ptr = skb_put(skb, count);
399         *ptr++ = cmd;   /* KISS command */
400
401         memcpy(ptr, sp->cooked_buf + 1, count);
402         skb->mac.raw = skb->data;
403         skb->protocol = htons(ETH_P_AX25);
404         netif_rx(skb);
405         sp->dev->last_rx = jiffies;
406         sp->stats.rx_packets++;
407
408         return;
409
410 out_mem:
411         sp->stats.rx_dropped++;
412 }
413
414
415 /* ----------------------------------------------------------------------- */
416
417 /*
418  * We have a potential race on dereferencing tty->disc_data, because the tty
419  * layer provides no locking at all - thus one cpu could be running
420  * sixpack_receive_buf while another calls sixpack_close, which zeroes
421  * tty->disc_data and frees the memory that sixpack_receive_buf is using.  The
422  * best way to fix this is to use a rwlock in the tty struct, but for now we
423  * use a single global rwlock for all ttys in ppp line discipline.
424  */
425 static DEFINE_RWLOCK(disc_data_lock);
426                                                                                 
427 static struct sixpack *sp_get(struct tty_struct *tty)
428 {
429         struct sixpack *sp;
430
431         read_lock(&disc_data_lock);
432         sp = tty->disc_data;
433         if (sp)
434                 atomic_inc(&sp->refcnt);
435         read_unlock(&disc_data_lock);
436
437         return sp;
438 }
439
440 static void sp_put(struct sixpack *sp)
441 {
442         if (atomic_dec_and_test(&sp->refcnt))
443                 up(&sp->dead_sem);
444 }
445
446 /*
447  * Called by the TTY driver when there's room for more data.  If we have
448  * more packets to send, we send them here.
449  */
450 static void sixpack_write_wakeup(struct tty_struct *tty)
451 {
452         struct sixpack *sp = sp_get(tty);
453         int actual;
454
455         if (!sp)
456                 return;
457         if (sp->xleft <= 0)  {
458                 /* Now serial buffer is almost free & we can start
459                  * transmission of another packet */
460                 sp->stats.tx_packets++;
461                 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
462                 sp->tx_enable = 0;
463                 netif_wake_queue(sp->dev);
464                 goto out;
465         }
466
467         if (sp->tx_enable) {
468                 actual = tty->driver->write(tty, sp->xhead, sp->xleft);
469                 sp->xleft -= actual;
470                 sp->xhead += actual;
471         }
472
473 out:
474         sp_put(sp);
475 }
476
477 /* ----------------------------------------------------------------------- */
478
479 static int sixpack_receive_room(struct tty_struct *tty)
480 {
481         return 65536;  /* We can handle an infinite amount of data. :-) */
482 }
483
484 /*
485  * Handle the 'receiver data ready' interrupt.
486  * This function is called by the 'tty_io' module in the kernel when
487  * a block of 6pack data has been received, which can now be decapsulated
488  * and sent on to some IP layer for further processing.
489  */
490 static void sixpack_receive_buf(struct tty_struct *tty,
491         const unsigned char *cp, char *fp, int count)
492 {
493         struct sixpack *sp;
494         unsigned char buf[512];
495         int count1;
496
497         if (!count)
498                 return;
499
500         sp = sp_get(tty);
501         if (!sp)
502                 return;
503
504         memcpy(buf, cp, count < sizeof(buf) ? count : sizeof(buf));
505
506         /* Read the characters out of the buffer */
507
508         count1 = count;
509         while (count) {
510                 count--;
511                 if (fp && *fp++) {
512                         if (!test_and_set_bit(SIXPF_ERROR, &sp->flags))
513                                 sp->stats.rx_errors++;
514                         continue;
515                 }
516         }
517         sixpack_decode(sp, buf, count1);
518
519         sp_put(sp);
520         if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
521             && tty->driver->unthrottle)
522                 tty->driver->unthrottle(tty);
523 }
524
525 /*
526  * Try to resync the TNC. Called by the resync timer defined in
527  * decode_prio_command
528  */
529
530 #define TNC_UNINITIALIZED       0
531 #define TNC_UNSYNC_STARTUP      1
532 #define TNC_UNSYNCED            2
533 #define TNC_IN_SYNC             3
534
535 static void __tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
536 {
537         char *msg;
538
539         switch (new_tnc_state) {
540         default:                        /* gcc oh piece-o-crap ... */
541         case TNC_UNSYNC_STARTUP:
542                 msg = "Synchronizing with TNC";
543                 break;
544         case TNC_UNSYNCED:
545                 msg = "Lost synchronization with TNC\n";
546                 break;
547         case TNC_IN_SYNC:
548                 msg = "Found TNC";
549                 break;
550         }
551
552         sp->tnc_state = new_tnc_state;
553         printk(KERN_INFO "%s: %s\n", sp->dev->name, msg);
554 }
555
556 static inline void tnc_set_sync_state(struct sixpack *sp, int new_tnc_state)
557 {
558         int old_tnc_state = sp->tnc_state;
559
560         if (old_tnc_state != new_tnc_state)
561                 __tnc_set_sync_state(sp, new_tnc_state);
562 }
563
564 static void resync_tnc(unsigned long channel)
565 {
566         struct sixpack *sp = (struct sixpack *) channel;
567         static char resync_cmd = 0xe8;
568
569         /* clear any data that might have been received */
570
571         sp->rx_count = 0;
572         sp->rx_count_cooked = 0;
573
574         /* reset state machine */
575
576         sp->status = 1;
577         sp->status1 = 1;
578         sp->status2 = 0;
579
580         /* resync the TNC */
581
582         sp->led_state = 0x60;
583         sp->tty->driver->write(sp->tty, &sp->led_state, 1);
584         sp->tty->driver->write(sp->tty, &resync_cmd, 1);
585
586
587         /* Start resync timer again -- the TNC might be still absent */
588
589         del_timer(&sp->resync_t);
590         sp->resync_t.data       = (unsigned long) sp;
591         sp->resync_t.function   = resync_tnc;
592         sp->resync_t.expires    = jiffies + SIXP_RESYNC_TIMEOUT;
593         add_timer(&sp->resync_t);
594 }
595
596 static inline int tnc_init(struct sixpack *sp)
597 {
598         unsigned char inbyte = 0xe8;
599
600         tnc_set_sync_state(sp, TNC_UNSYNC_STARTUP);
601
602         sp->tty->driver->write(sp->tty, &inbyte, 1);
603
604         del_timer(&sp->resync_t);
605         sp->resync_t.data = (unsigned long) sp;
606         sp->resync_t.function = resync_tnc;
607         sp->resync_t.expires = jiffies + SIXP_RESYNC_TIMEOUT;
608         add_timer(&sp->resync_t);
609
610         return 0;
611 }
612
613 /*
614  * Open the high-level part of the 6pack channel.
615  * This function is called by the TTY module when the
616  * 6pack line discipline is called for.  Because we are
617  * sure the tty line exists, we only have to link it to
618  * a free 6pcack channel...
619  */
620 static int sixpack_open(struct tty_struct *tty)
621 {
622         char *rbuff = NULL, *xbuff = NULL;
623         struct net_device *dev;
624         struct sixpack *sp;
625         unsigned long len;
626         int err = 0;
627
628         if (!capable(CAP_NET_ADMIN))
629                 return -EPERM;
630
631         dev = alloc_netdev(sizeof(struct sixpack), "sp%d", sp_setup);
632         if (!dev) {
633                 err = -ENOMEM;
634                 goto out;
635         }
636
637         sp = netdev_priv(dev);
638         sp->dev = dev;
639
640         spin_lock_init(&sp->lock);
641         atomic_set(&sp->refcnt, 1);
642         init_MUTEX_LOCKED(&sp->dead_sem);
643
644         /* !!! length of the buffers. MTU is IP MTU, not PACLEN!  */
645
646         len = dev->mtu * 2;
647
648         rbuff = kmalloc(len + 4, GFP_KERNEL);
649         xbuff = kmalloc(len + 4, GFP_KERNEL);
650
651         if (rbuff == NULL || xbuff == NULL) {
652                 err = -ENOBUFS;
653                 goto out_free;
654         }
655
656         spin_lock_bh(&sp->lock);
657
658         sp->tty = tty;
659
660         sp->rbuff       = rbuff;
661         sp->xbuff       = xbuff;
662
663         sp->mtu         = AX25_MTU + 73;
664         sp->buffsize    = len;
665         sp->rcount      = 0;
666         sp->rx_count    = 0;
667         sp->rx_count_cooked = 0;
668         sp->xleft       = 0;
669
670         sp->flags       = 0;            /* Clear ESCAPE & ERROR flags */
671
672         sp->duplex      = 0;
673         sp->tx_delay    = SIXP_TXDELAY;
674         sp->persistence = SIXP_PERSIST;
675         sp->slottime    = SIXP_SLOTTIME;
676         sp->led_state   = 0x60;
677         sp->status      = 1;
678         sp->status1     = 1;
679         sp->status2     = 0;
680         sp->tx_enable   = 0;
681
682         netif_start_queue(dev);
683
684         init_timer(&sp->tx_t);
685         init_timer(&sp->resync_t);
686
687         spin_unlock_bh(&sp->lock);
688
689         /* Done.  We have linked the TTY line to a channel. */
690         tty->disc_data = sp;
691
692         /* Now we're ready to register. */
693         if (register_netdev(dev))
694                 goto out_free;
695
696         tnc_init(sp);
697
698         return 0;
699
700 out_free:
701         kfree(xbuff);
702         kfree(rbuff);
703
704         if (dev)
705                 free_netdev(dev);
706
707 out:
708         return err;
709 }
710
711
712 /*
713  * Close down a 6pack channel.
714  * This means flushing out any pending queues, and then restoring the
715  * TTY line discipline to what it was before it got hooked to 6pack
716  * (which usually is TTY again).
717  */
718 static void sixpack_close(struct tty_struct *tty)
719 {
720         struct sixpack *sp;
721
722         write_lock(&disc_data_lock);
723         sp = tty->disc_data;
724         tty->disc_data = NULL;
725         write_unlock(&disc_data_lock);
726         if (sp == 0)
727                 return;
728
729         /*
730          * We have now ensured that nobody can start using ap from now on, but
731          * we have to wait for all existing users to finish.
732          */
733         if (!atomic_dec_and_test(&sp->refcnt))
734                 down(&sp->dead_sem);
735
736         unregister_netdev(sp->dev);
737
738         del_timer(&sp->tx_t);
739         del_timer(&sp->resync_t);
740
741         /* Free all 6pack frame buffers. */
742         kfree(sp->rbuff);
743         kfree(sp->xbuff);
744 }
745
746 /* Perform I/O control on an active 6pack channel. */
747 static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
748         unsigned int cmd, unsigned long arg)
749 {
750         struct sixpack *sp = sp_get(tty);
751         struct net_device *dev = sp->dev;
752         unsigned int tmp, err;
753
754         if (!sp)
755                 return -ENXIO;
756
757         switch(cmd) {
758         case SIOCGIFNAME:
759                 err = copy_to_user((void *) arg, dev->name,
760                                    strlen(dev->name) + 1) ? -EFAULT : 0;
761                 break;
762
763         case SIOCGIFENCAP:
764                 err = put_user(0, (int __user *)arg);
765                 break;
766
767         case SIOCSIFENCAP:
768                 if (get_user(tmp, (int __user *) arg)) {
769                         err = -EFAULT;
770                         break;
771                 }
772
773                 sp->mode = tmp;
774                 dev->addr_len        = AX25_ADDR_LEN;
775                 dev->hard_header_len = AX25_KISS_HEADER_LEN +
776                                        AX25_MAX_HEADER_LEN + 3;
777                 dev->type            = ARPHRD_AX25;
778
779                 err = 0;
780                 break;
781
782          case SIOCSIFHWADDR: {
783                 char addr[AX25_ADDR_LEN];
784
785                 if (copy_from_user(&addr,
786                                    (void __user *) arg, AX25_ADDR_LEN)) {
787                         err = -EFAULT;
788                         break;
789                 }
790
791                 spin_lock_irq(&dev->xmit_lock);
792                 memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
793                 spin_unlock_irq(&dev->xmit_lock);
794
795                 err = 0;
796                 break;
797         }
798
799         /* Allow stty to read, but not set, the serial port */
800         case TCGETS:
801         case TCGETA:
802                 err = n_tty_ioctl(tty, (struct file *) file, cmd, arg);
803                 break;
804
805         default:
806                 err = -ENOIOCTLCMD;
807         }
808
809         sp_put(sp);
810
811         return err;
812 }
813
814 static struct tty_ldisc sp_ldisc = {
815         .owner          = THIS_MODULE,
816         .magic          = TTY_LDISC_MAGIC,
817         .name           = "6pack",
818         .open           = sixpack_open,
819         .close          = sixpack_close,
820         .ioctl          = sixpack_ioctl,
821         .receive_buf    = sixpack_receive_buf,
822         .receive_room   = sixpack_receive_room,
823         .write_wakeup   = sixpack_write_wakeup,
824 };
825
826 /* Initialize 6pack control device -- register 6pack line discipline */
827
828 static char msg_banner[]  __initdata = KERN_INFO \
829         "AX.25: 6pack driver, " SIXPACK_VERSION "\n";
830 static char msg_regfail[] __initdata = KERN_ERR  \
831         "6pack: can't register line discipline (err = %d)\n";
832
833 static int __init sixpack_init_driver(void)
834 {
835         int status;
836
837         printk(msg_banner);
838
839         /* Register the provided line protocol discipline */
840         if ((status = tty_register_ldisc(N_6PACK, &sp_ldisc)) != 0)
841                 printk(msg_regfail, status);
842
843         return status;
844 }
845
846 static const char msg_unregfail[] __exitdata = KERN_ERR \
847         "6pack: can't unregister line discipline (err = %d)\n";
848
849 static void __exit sixpack_exit_driver(void)
850 {
851         int ret;
852
853         if ((ret = tty_register_ldisc(N_6PACK, NULL)))
854                 printk(msg_unregfail, ret);
855 }
856
857 /* encode an AX.25 packet into 6pack */
858
859 static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
860         int length, unsigned char tx_delay)
861 {
862         int count = 0;
863         unsigned char checksum = 0, buf[400];
864         int raw_count = 0;
865
866         tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK;
867         tx_buf_raw[raw_count++] = SIXP_SEOF;
868
869         buf[0] = tx_delay;
870         for (count = 1; count < length; count++)
871                 buf[count] = tx_buf[count];
872
873         for (count = 0; count < length; count++)
874                 checksum += buf[count];
875         buf[length] = (unsigned char) 0xff - checksum;
876
877         for (count = 0; count <= length; count++) {
878                 if ((count % 3) == 0) {
879                         tx_buf_raw[raw_count++] = (buf[count] & 0x3f);
880                         tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30);
881                 } else if ((count % 3) == 1) {
882                         tx_buf_raw[raw_count++] |= (buf[count] & 0x0f);
883                         tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x3c);
884                 } else {
885                         tx_buf_raw[raw_count++] |= (buf[count] & 0x03);
886                         tx_buf_raw[raw_count++] = (buf[count] >> 2);
887                 }
888         }
889         if ((length % 3) != 2)
890                 raw_count++;
891         tx_buf_raw[raw_count++] = SIXP_SEOF;
892         return raw_count;
893 }
894
895 /* decode 4 sixpack-encoded bytes into 3 data bytes */
896
897 static void decode_data(struct sixpack *sp, unsigned char inbyte)
898 {
899         unsigned char *buf;
900
901         if (sp->rx_count != 3) {
902                 sp->raw_buf[sp->rx_count++] = inbyte;
903
904                 return;
905         }
906
907         buf = sp->raw_buf;
908         sp->cooked_buf[sp->rx_count_cooked++] =
909                 buf[0] | ((buf[1] << 2) & 0xc0);
910         sp->cooked_buf[sp->rx_count_cooked++] =
911                 (buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0);
912         sp->cooked_buf[sp->rx_count_cooked++] =
913                 (buf[2] & 0x03) | (inbyte << 2);
914         sp->rx_count = 0;
915 }
916
917 /* identify and execute a 6pack priority command byte */
918
919 static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
920 {
921         unsigned char channel;
922         int actual;
923
924         channel = cmd & SIXP_CHN_MASK;
925         if ((cmd & SIXP_PRIO_DATA_MASK) != 0) {     /* idle ? */
926
927         /* RX and DCD flags can only be set in the same prio command,
928            if the DCD flag has been set without the RX flag in the previous
929            prio command. If DCD has not been set before, something in the
930            transmission has gone wrong. In this case, RX and DCD are
931            cleared in order to prevent the decode_data routine from
932            reading further data that might be corrupt. */
933
934                 if (((sp->status & SIXP_DCD_MASK) == 0) &&
935                         ((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) {
936                                 if (sp->status != 1)
937                                         printk(KERN_DEBUG "6pack: protocol violation\n");
938                                 else
939                                         sp->status = 0;
940                                 cmd &= !SIXP_RX_DCD_MASK;
941                 }
942                 sp->status = cmd & SIXP_PRIO_DATA_MASK;
943         } else { /* output watchdog char if idle */
944                 if ((sp->status2 != 0) && (sp->duplex == 1)) {
945                         sp->led_state = 0x70;
946                         sp->tty->driver->write(sp->tty, &sp->led_state, 1);
947                         sp->tx_enable = 1;
948                         actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
949                         sp->xleft -= actual;
950                         sp->xhead += actual;
951                         sp->led_state = 0x60;
952                         sp->status2 = 0;
953
954                 }
955         }
956
957         /* needed to trigger the TNC watchdog */
958         sp->tty->driver->write(sp->tty, &sp->led_state, 1);
959
960         /* if the state byte has been received, the TNC is present,
961            so the resync timer can be reset. */
962
963         if (sp->tnc_state == TNC_IN_SYNC) {
964                 del_timer(&sp->resync_t);
965                 sp->resync_t.data       = (unsigned long) sp;
966                 sp->resync_t.function   = resync_tnc;
967                 sp->resync_t.expires    = jiffies + SIXP_INIT_RESYNC_TIMEOUT;
968                 add_timer(&sp->resync_t);
969         }
970
971         sp->status1 = cmd & SIXP_PRIO_DATA_MASK;
972 }
973
974 /* identify and execute a standard 6pack command byte */
975
976 static void decode_std_command(struct sixpack *sp, unsigned char cmd)
977 {
978         unsigned char checksum = 0, rest = 0, channel;
979         short i;
980
981         channel = cmd & SIXP_CHN_MASK;
982         switch (cmd & SIXP_CMD_MASK) {     /* normal command */
983         case SIXP_SEOF:
984                 if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) {
985                         if ((sp->status & SIXP_RX_DCD_MASK) ==
986                                 SIXP_RX_DCD_MASK) {
987                                 sp->led_state = 0x68;
988                                 sp->tty->driver->write(sp->tty, &sp->led_state, 1);
989                         }
990                 } else {
991                         sp->led_state = 0x60;
992                         /* fill trailing bytes with zeroes */
993                         sp->tty->driver->write(sp->tty, &sp->led_state, 1);
994                         rest = sp->rx_count;
995                         if (rest != 0)
996                                  for (i = rest; i <= 3; i++)
997                                         decode_data(sp, 0);
998                         if (rest == 2)
999                                 sp->rx_count_cooked -= 2;
1000                         else if (rest == 3)
1001                                 sp->rx_count_cooked -= 1;
1002                         for (i = 0; i < sp->rx_count_cooked; i++)
1003                                 checksum += sp->cooked_buf[i];
1004                         if (checksum != SIXP_CHKSUM) {
1005                                 printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum);
1006                         } else {
1007                                 sp->rcount = sp->rx_count_cooked-2;
1008                                 sp_bump(sp, 0);
1009                         }
1010                         sp->rx_count_cooked = 0;
1011                 }
1012                 break;
1013         case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n");
1014                 break;
1015         case SIXP_RX_ORUN: printk(KERN_DEBUG "6pack: RX overrun\n");
1016                 break;
1017         case SIXP_RX_BUF_OVL:
1018                 printk(KERN_DEBUG "6pack: RX buffer overflow\n");
1019         }
1020 }
1021
1022 /* decode a 6pack packet */
1023
1024 static void
1025 sixpack_decode(struct sixpack *sp, unsigned char *pre_rbuff, int count)
1026 {
1027         unsigned char inbyte;
1028         int count1;
1029
1030         for (count1 = 0; count1 < count; count1++) {
1031                 inbyte = pre_rbuff[count1];
1032                 if (inbyte == SIXP_FOUND_TNC) {
1033                         tnc_set_sync_state(sp, TNC_IN_SYNC);
1034                         del_timer(&sp->resync_t);
1035                 }
1036                 if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
1037                         decode_prio_command(sp, inbyte);
1038                 else if ((inbyte & SIXP_STD_CMD_MASK) != 0)
1039                         decode_std_command(sp, inbyte);
1040                 else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)
1041                         decode_data(sp, inbyte);
1042         }
1043 }
1044
1045 MODULE_AUTHOR("Ralf Baechle DO1GRB <ralf@linux-mips.org>");
1046 MODULE_DESCRIPTION("6pack driver for AX.25");
1047 MODULE_LICENSE("GPL");
1048 MODULE_ALIAS_LDISC(N_6PACK);
1049
1050 module_init(sixpack_init_driver);
1051 module_exit(sixpack_exit_driver);