[PATCH] 6pack Timer initialization
[safe/jmp/linux-2.6] / 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         sp->tx_t.function = sp_xmit_on_air;
672         sp->tx_t.data = (unsigned long) sp;
673
674         init_timer(&sp->resync_t);
675
676         spin_unlock_bh(&sp->lock);
677
678         /* Done.  We have linked the TTY line to a channel. */
679         tty->disc_data = sp;
680
681         /* Now we're ready to register. */
682         if (register_netdev(dev))
683                 goto out_free;
684
685         tnc_init(sp);
686
687         return 0;
688
689 out_free:
690         kfree(xbuff);
691         kfree(rbuff);
692
693         if (dev)
694                 free_netdev(dev);
695
696 out:
697         return err;
698 }
699
700
701 /*
702  * Close down a 6pack channel.
703  * This means flushing out any pending queues, and then restoring the
704  * TTY line discipline to what it was before it got hooked to 6pack
705  * (which usually is TTY again).
706  */
707 static void sixpack_close(struct tty_struct *tty)
708 {
709         struct sixpack *sp;
710
711         write_lock(&disc_data_lock);
712         sp = tty->disc_data;
713         tty->disc_data = NULL;
714         write_unlock(&disc_data_lock);
715         if (sp == 0)
716                 return;
717
718         /*
719          * We have now ensured that nobody can start using ap from now on, but
720          * we have to wait for all existing users to finish.
721          */
722         if (!atomic_dec_and_test(&sp->refcnt))
723                 down(&sp->dead_sem);
724
725         unregister_netdev(sp->dev);
726
727         del_timer(&sp->tx_t);
728         del_timer(&sp->resync_t);
729
730         /* Free all 6pack frame buffers. */
731         kfree(sp->rbuff);
732         kfree(sp->xbuff);
733 }
734
735 /* Perform I/O control on an active 6pack channel. */
736 static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
737         unsigned int cmd, unsigned long arg)
738 {
739         struct sixpack *sp = sp_get(tty);
740         struct net_device *dev = sp->dev;
741         unsigned int tmp, err;
742
743         if (!sp)
744                 return -ENXIO;
745
746         switch(cmd) {
747         case SIOCGIFNAME:
748                 err = copy_to_user((void __user *) arg, dev->name,
749                                    strlen(dev->name) + 1) ? -EFAULT : 0;
750                 break;
751
752         case SIOCGIFENCAP:
753                 err = put_user(0, (int __user *) arg);
754                 break;
755
756         case SIOCSIFENCAP:
757                 if (get_user(tmp, (int __user *) arg)) {
758                         err = -EFAULT;
759                         break;
760                 }
761
762                 sp->mode = tmp;
763                 dev->addr_len        = AX25_ADDR_LEN;
764                 dev->hard_header_len = AX25_KISS_HEADER_LEN +
765                                        AX25_MAX_HEADER_LEN + 3;
766                 dev->type            = ARPHRD_AX25;
767
768                 err = 0;
769                 break;
770
771          case SIOCSIFHWADDR: {
772                 char addr[AX25_ADDR_LEN];
773
774                 if (copy_from_user(&addr,
775                                    (void __user *) arg, AX25_ADDR_LEN)) {
776                         err = -EFAULT;
777                         break;
778                 }
779
780                 spin_lock_irq(&dev->xmit_lock);
781                 memcpy(dev->dev_addr, &addr, AX25_ADDR_LEN);
782                 spin_unlock_irq(&dev->xmit_lock);
783
784                 err = 0;
785                 break;
786         }
787
788         /* Allow stty to read, but not set, the serial port */
789         case TCGETS:
790         case TCGETA:
791                 err = n_tty_ioctl(tty, (struct file *) file, cmd, arg);
792                 break;
793
794         default:
795                 err = -ENOIOCTLCMD;
796         }
797
798         sp_put(sp);
799
800         return err;
801 }
802
803 static struct tty_ldisc sp_ldisc = {
804         .owner          = THIS_MODULE,
805         .magic          = TTY_LDISC_MAGIC,
806         .name           = "6pack",
807         .open           = sixpack_open,
808         .close          = sixpack_close,
809         .ioctl          = sixpack_ioctl,
810         .receive_buf    = sixpack_receive_buf,
811         .receive_room   = sixpack_receive_room,
812         .write_wakeup   = sixpack_write_wakeup,
813 };
814
815 /* Initialize 6pack control device -- register 6pack line discipline */
816
817 static char msg_banner[]  __initdata = KERN_INFO \
818         "AX.25: 6pack driver, " SIXPACK_VERSION "\n";
819 static char msg_regfail[] __initdata = KERN_ERR  \
820         "6pack: can't register line discipline (err = %d)\n";
821
822 static int __init sixpack_init_driver(void)
823 {
824         int status;
825
826         printk(msg_banner);
827
828         /* Register the provided line protocol discipline */
829         if ((status = tty_register_ldisc(N_6PACK, &sp_ldisc)) != 0)
830                 printk(msg_regfail, status);
831
832         return status;
833 }
834
835 static const char msg_unregfail[] __exitdata = KERN_ERR \
836         "6pack: can't unregister line discipline (err = %d)\n";
837
838 static void __exit sixpack_exit_driver(void)
839 {
840         int ret;
841
842         if ((ret = tty_unregister_ldisc(N_6PACK)))
843                 printk(msg_unregfail, ret);
844 }
845
846 /* encode an AX.25 packet into 6pack */
847
848 static int encode_sixpack(unsigned char *tx_buf, unsigned char *tx_buf_raw,
849         int length, unsigned char tx_delay)
850 {
851         int count = 0;
852         unsigned char checksum = 0, buf[400];
853         int raw_count = 0;
854
855         tx_buf_raw[raw_count++] = SIXP_PRIO_CMD_MASK | SIXP_TX_MASK;
856         tx_buf_raw[raw_count++] = SIXP_SEOF;
857
858         buf[0] = tx_delay;
859         for (count = 1; count < length; count++)
860                 buf[count] = tx_buf[count];
861
862         for (count = 0; count < length; count++)
863                 checksum += buf[count];
864         buf[length] = (unsigned char) 0xff - checksum;
865
866         for (count = 0; count <= length; count++) {
867                 if ((count % 3) == 0) {
868                         tx_buf_raw[raw_count++] = (buf[count] & 0x3f);
869                         tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x30);
870                 } else if ((count % 3) == 1) {
871                         tx_buf_raw[raw_count++] |= (buf[count] & 0x0f);
872                         tx_buf_raw[raw_count] = ((buf[count] >> 2) & 0x3c);
873                 } else {
874                         tx_buf_raw[raw_count++] |= (buf[count] & 0x03);
875                         tx_buf_raw[raw_count++] = (buf[count] >> 2);
876                 }
877         }
878         if ((length % 3) != 2)
879                 raw_count++;
880         tx_buf_raw[raw_count++] = SIXP_SEOF;
881         return raw_count;
882 }
883
884 /* decode 4 sixpack-encoded bytes into 3 data bytes */
885
886 static void decode_data(struct sixpack *sp, unsigned char inbyte)
887 {
888         unsigned char *buf;
889
890         if (sp->rx_count != 3) {
891                 sp->raw_buf[sp->rx_count++] = inbyte;
892
893                 return;
894         }
895
896         buf = sp->raw_buf;
897         sp->cooked_buf[sp->rx_count_cooked++] =
898                 buf[0] | ((buf[1] << 2) & 0xc0);
899         sp->cooked_buf[sp->rx_count_cooked++] =
900                 (buf[1] & 0x0f) | ((buf[2] << 2) & 0xf0);
901         sp->cooked_buf[sp->rx_count_cooked++] =
902                 (buf[2] & 0x03) | (inbyte << 2);
903         sp->rx_count = 0;
904 }
905
906 /* identify and execute a 6pack priority command byte */
907
908 static void decode_prio_command(struct sixpack *sp, unsigned char cmd)
909 {
910         unsigned char channel;
911         int actual;
912
913         channel = cmd & SIXP_CHN_MASK;
914         if ((cmd & SIXP_PRIO_DATA_MASK) != 0) {     /* idle ? */
915
916         /* RX and DCD flags can only be set in the same prio command,
917            if the DCD flag has been set without the RX flag in the previous
918            prio command. If DCD has not been set before, something in the
919            transmission has gone wrong. In this case, RX and DCD are
920            cleared in order to prevent the decode_data routine from
921            reading further data that might be corrupt. */
922
923                 if (((sp->status & SIXP_DCD_MASK) == 0) &&
924                         ((cmd & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)) {
925                                 if (sp->status != 1)
926                                         printk(KERN_DEBUG "6pack: protocol violation\n");
927                                 else
928                                         sp->status = 0;
929                                 cmd &= !SIXP_RX_DCD_MASK;
930                 }
931                 sp->status = cmd & SIXP_PRIO_DATA_MASK;
932         } else { /* output watchdog char if idle */
933                 if ((sp->status2 != 0) && (sp->duplex == 1)) {
934                         sp->led_state = 0x70;
935                         sp->tty->driver->write(sp->tty, &sp->led_state, 1);
936                         sp->tx_enable = 1;
937                         actual = sp->tty->driver->write(sp->tty, sp->xbuff, sp->status2);
938                         sp->xleft -= actual;
939                         sp->xhead += actual;
940                         sp->led_state = 0x60;
941                         sp->status2 = 0;
942
943                 }
944         }
945
946         /* needed to trigger the TNC watchdog */
947         sp->tty->driver->write(sp->tty, &sp->led_state, 1);
948
949         /* if the state byte has been received, the TNC is present,
950            so the resync timer can be reset. */
951
952         if (sp->tnc_state == TNC_IN_SYNC) {
953                 del_timer(&sp->resync_t);
954                 sp->resync_t.data       = (unsigned long) sp;
955                 sp->resync_t.function   = resync_tnc;
956                 sp->resync_t.expires    = jiffies + SIXP_INIT_RESYNC_TIMEOUT;
957                 add_timer(&sp->resync_t);
958         }
959
960         sp->status1 = cmd & SIXP_PRIO_DATA_MASK;
961 }
962
963 /* identify and execute a standard 6pack command byte */
964
965 static void decode_std_command(struct sixpack *sp, unsigned char cmd)
966 {
967         unsigned char checksum = 0, rest = 0, channel;
968         short i;
969
970         channel = cmd & SIXP_CHN_MASK;
971         switch (cmd & SIXP_CMD_MASK) {     /* normal command */
972         case SIXP_SEOF:
973                 if ((sp->rx_count == 0) && (sp->rx_count_cooked == 0)) {
974                         if ((sp->status & SIXP_RX_DCD_MASK) ==
975                                 SIXP_RX_DCD_MASK) {
976                                 sp->led_state = 0x68;
977                                 sp->tty->driver->write(sp->tty, &sp->led_state, 1);
978                         }
979                 } else {
980                         sp->led_state = 0x60;
981                         /* fill trailing bytes with zeroes */
982                         sp->tty->driver->write(sp->tty, &sp->led_state, 1);
983                         rest = sp->rx_count;
984                         if (rest != 0)
985                                  for (i = rest; i <= 3; i++)
986                                         decode_data(sp, 0);
987                         if (rest == 2)
988                                 sp->rx_count_cooked -= 2;
989                         else if (rest == 3)
990                                 sp->rx_count_cooked -= 1;
991                         for (i = 0; i < sp->rx_count_cooked; i++)
992                                 checksum += sp->cooked_buf[i];
993                         if (checksum != SIXP_CHKSUM) {
994                                 printk(KERN_DEBUG "6pack: bad checksum %2.2x\n", checksum);
995                         } else {
996                                 sp->rcount = sp->rx_count_cooked-2;
997                                 sp_bump(sp, 0);
998                         }
999                         sp->rx_count_cooked = 0;
1000                 }
1001                 break;
1002         case SIXP_TX_URUN: printk(KERN_DEBUG "6pack: TX underrun\n");
1003                 break;
1004         case SIXP_RX_ORUN: printk(KERN_DEBUG "6pack: RX overrun\n");
1005                 break;
1006         case SIXP_RX_BUF_OVL:
1007                 printk(KERN_DEBUG "6pack: RX buffer overflow\n");
1008         }
1009 }
1010
1011 /* decode a 6pack packet */
1012
1013 static void
1014 sixpack_decode(struct sixpack *sp, unsigned char *pre_rbuff, int count)
1015 {
1016         unsigned char inbyte;
1017         int count1;
1018
1019         for (count1 = 0; count1 < count; count1++) {
1020                 inbyte = pre_rbuff[count1];
1021                 if (inbyte == SIXP_FOUND_TNC) {
1022                         tnc_set_sync_state(sp, TNC_IN_SYNC);
1023                         del_timer(&sp->resync_t);
1024                 }
1025                 if ((inbyte & SIXP_PRIO_CMD_MASK) != 0)
1026                         decode_prio_command(sp, inbyte);
1027                 else if ((inbyte & SIXP_STD_CMD_MASK) != 0)
1028                         decode_std_command(sp, inbyte);
1029                 else if ((sp->status & SIXP_RX_DCD_MASK) == SIXP_RX_DCD_MASK)
1030                         decode_data(sp, inbyte);
1031         }
1032 }
1033
1034 MODULE_AUTHOR("Ralf Baechle DO1GRB <ralf@linux-mips.org>");
1035 MODULE_DESCRIPTION("6pack driver for AX.25");
1036 MODULE_LICENSE("GPL");
1037 MODULE_ALIAS_LDISC(N_6PACK);
1038
1039 module_init(sixpack_init_driver);
1040 module_exit(sixpack_exit_driver);