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