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