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