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