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