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