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