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