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