1 /*
2  *	Things to sort out:
3  *
4  *	o	tbusy handling
5  *	o	allow users to set the parameters
6  *	o	sync/async switching ?
7  *
8  *	Note: This does _not_ implement CCITT X.25 asynchronous framing
9  *	recommendations. Its primarily for testing purposes. If you wanted
10  *	to do CCITT then in theory all you need is to nick the HDLC async
11  *	checksum routines from ppp.c
12  *      Changes:
13  *
14  *	2000-10-29	Henner Eisen	lapb_data_indication() return status.
15  */
16 
17 #include <linux/module.h>
18 
19 #include <asm/system.h>
20 #include <asm/uaccess.h>
21 #include <asm/bitops.h>
22 #include <linux/string.h>
23 #include <linux/mm.h>
24 #include <linux/interrupt.h>
25 #include <linux/in.h>
26 #include <linux/tty.h>
27 #include <linux/errno.h>
28 #include <linux/netdevice.h>
29 #include <linux/etherdevice.h>
30 #include <linux/skbuff.h>
31 #include <linux/if_arp.h>
32 #include <linux/x25.h>
33 #include <linux/lapb.h>
34 #include <linux/init.h>
35 #include "x25_asy.h"
36 
37 typedef struct x25_ctrl {
38 	struct x25_asy	ctrl;		/* X.25 things			*/
39 	struct net_device	dev;		/* the device			*/
40 } x25_asy_ctrl_t;
41 
42 static x25_asy_ctrl_t	**x25_asy_ctrls = NULL;
43 
44 int x25_asy_maxdev = SL_NRUNIT;		/* Can be overridden with insmod! */
45 
46 MODULE_PARM(x25_asy_maxdev, "i");
47 MODULE_LICENSE("GPL");
48 
49 static struct tty_ldisc	x25_ldisc;
50 
51 static int x25_asy_esc(unsigned char *p, unsigned char *d, int len);
52 static void x25_asy_unesc(struct x25_asy *sl, unsigned char c);
53 
54 /* Find a free X.25 channel, and link in this `tty' line. */
x25_asy_alloc(void)55 static inline struct x25_asy *x25_asy_alloc(void)
56 {
57 	x25_asy_ctrl_t *slp = NULL;
58 	int i;
59 
60 	if (x25_asy_ctrls == NULL)
61 		return NULL;	/* Master array missing ! */
62 
63 	for (i = 0; i < x25_asy_maxdev; i++)
64 	{
65 		slp = x25_asy_ctrls[i];
66 		/* Not allocated ? */
67 		if (slp == NULL)
68 			break;
69 		/* Not in use ? */
70 		if (!test_and_set_bit(SLF_INUSE, &slp->ctrl.flags))
71 			break;
72 	}
73 	/* SLP is set.. */
74 
75 	/* Sorry, too many, all slots in use */
76 	if (i >= x25_asy_maxdev)
77 		return NULL;
78 
79 	/* If no channels are available, allocate one */
80 	if (!slp &&
81 	    (x25_asy_ctrls[i] = (x25_asy_ctrl_t *)kmalloc(sizeof(x25_asy_ctrl_t),
82 						    GFP_KERNEL)) != NULL) {
83 		slp = x25_asy_ctrls[i];
84 		memset(slp, 0, sizeof(x25_asy_ctrl_t));
85 
86 		/* Initialize channel control data */
87 		set_bit(SLF_INUSE, &slp->ctrl.flags);
88 		slp->ctrl.tty         = NULL;
89 		sprintf(slp->dev.name, "x25asy%d", i);
90 		slp->dev.base_addr    = i;
91 		slp->dev.priv         = (void*)&(slp->ctrl);
92 		slp->dev.next         = NULL;
93 		slp->dev.init         = x25_asy_init;
94 	}
95 	if (slp != NULL)
96 	{
97 
98 		/* register device so that it can be ifconfig'ed       */
99 		/* x25_asy_init() will be called as a side-effect      */
100 		/* SIDE-EFFECT WARNING: x25_asy_init() CLEARS slp->ctrl ! */
101 
102 		if (register_netdev(&(slp->dev)) == 0)
103 		{
104 			/* (Re-)Set the INUSE bit.   Very Important! */
105 			set_bit(SLF_INUSE, &slp->ctrl.flags);
106 			slp->ctrl.dev = &(slp->dev);
107 			slp->dev.priv = (void*)&(slp->ctrl);
108 			return (&(slp->ctrl));
109 		}
110 		else
111 		{
112 			clear_bit(SLF_INUSE,&(slp->ctrl.flags));
113 			printk("x25_asy_alloc() - register_netdev() failure.\n");
114 		}
115 	}
116 	return NULL;
117 }
118 
119 
120 /* Free an X.25 channel. */
121 
x25_asy_free(struct x25_asy * sl)122 static inline void x25_asy_free(struct x25_asy *sl)
123 {
124 	/* Free all X.25 frame buffers. */
125 	if (sl->rbuff)  {
126 		kfree(sl->rbuff);
127 	}
128 	sl->rbuff = NULL;
129 	if (sl->xbuff)  {
130 		kfree(sl->xbuff);
131 	}
132 	sl->xbuff = NULL;
133 
134 	if (!test_and_clear_bit(SLF_INUSE, &sl->flags)) {
135 		printk("%s: x25_asy_free for already free unit.\n", sl->dev->name);
136 	}
137 }
138 
139 /* MTU has been changed by the IP layer. Unfortunately we are not told
140    about this, but we spot it ourselves and fix things up. We could be
141    in an upcall from the tty driver, or in an ip packet queue. */
142 
x25_asy_changed_mtu(struct x25_asy * sl)143 static void x25_asy_changed_mtu(struct x25_asy *sl)
144 {
145 	struct net_device *dev = sl->dev;
146 	unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
147 	int len;
148 	unsigned long flags;
149 
150 	len = dev->mtu * 2;
151 
152 	xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
153 	rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
154 
155 	if (xbuff == NULL || rbuff == NULL)
156 	{
157 		printk("%s: unable to grow X.25 buffers, MTU change cancelled.\n",
158 		       sl->dev->name);
159 		dev->mtu = sl->mtu;
160 		if (xbuff != NULL)
161 			kfree(xbuff);
162 		if (rbuff != NULL)
163 			kfree(rbuff);
164 		return;
165 	}
166 
167 	save_flags(flags);
168 	cli();
169 
170 	oxbuff    = sl->xbuff;
171 	sl->xbuff = xbuff;
172 	orbuff    = sl->rbuff;
173 	sl->rbuff = rbuff;
174 
175 	if (sl->xleft)  {
176 		if (sl->xleft <= len)  {
177 			memcpy(sl->xbuff, sl->xhead, sl->xleft);
178 		} else  {
179 			sl->xleft = 0;
180 			sl->tx_dropped++;
181 		}
182 	}
183 	sl->xhead = sl->xbuff;
184 
185 	if (sl->rcount)  {
186 		if (sl->rcount <= len) {
187 			memcpy(sl->rbuff, orbuff, sl->rcount);
188 		} else  {
189 			sl->rcount = 0;
190 			sl->rx_over_errors++;
191 			set_bit(SLF_ERROR, &sl->flags);
192 		}
193 	}
194 	sl->mtu      = dev->mtu;
195 
196 	sl->buffsize = len;
197 
198 	restore_flags(flags);
199 
200 	if (oxbuff != NULL)
201 		kfree(oxbuff);
202 	if (orbuff != NULL)
203 		kfree(orbuff);
204 }
205 
206 
207 /* Set the "sending" flag.  This must be atomic, hence the ASM. */
208 
x25_asy_lock(struct x25_asy * sl)209 static inline void x25_asy_lock(struct x25_asy *sl)
210 {
211 	netif_stop_queue(sl->dev);
212 }
213 
214 
215 /* Clear the "sending" flag.  This must be atomic, hence the ASM. */
216 
x25_asy_unlock(struct x25_asy * sl)217 static inline void x25_asy_unlock(struct x25_asy *sl)
218 {
219 	netif_wake_queue(sl->dev);
220 }
221 
222 /* Send one completely decapsulated IP datagram to the IP layer. */
223 
x25_asy_bump(struct x25_asy * sl)224 static void x25_asy_bump(struct x25_asy *sl)
225 {
226 	struct sk_buff *skb;
227 	int count;
228 	int err;
229 
230 	count = sl->rcount;
231 	sl->rx_bytes+=count;
232 
233 	skb = dev_alloc_skb(count+1);
234 	if (skb == NULL)
235 	{
236 		printk("%s: memory squeeze, dropping packet.\n", sl->dev->name);
237 		sl->rx_dropped++;
238 		return;
239 	}
240 	skb_push(skb,1);	/* LAPB internal control */
241 	skb->dev = sl->dev;
242 	memcpy(skb_put(skb,count), sl->rbuff, count);
243 	skb->mac.raw=skb->data;
244 	skb->protocol=htons(ETH_P_X25);
245 	if((err=lapb_data_received(sl,skb))!=LAPB_OK)
246 	{
247 		kfree_skb(skb);
248 		printk(KERN_DEBUG "x25_asy: data received err - %d\n",err);
249 	}
250 	else
251 	{
252 		netif_rx(skb);
253 		sl->rx_packets++;
254 	}
255 }
256 
257 /* Encapsulate one IP datagram and stuff into a TTY queue. */
x25_asy_encaps(struct x25_asy * sl,unsigned char * icp,int len)258 static void x25_asy_encaps(struct x25_asy *sl, unsigned char *icp, int len)
259 {
260 	unsigned char *p;
261 	int actual, count;
262 
263 
264 	if (sl->mtu != sl->dev->mtu) {	/* Someone has been ifconfigging */
265 
266 		x25_asy_changed_mtu(sl);
267 	}
268 
269 	if (len > sl->mtu)
270 	{		/* Sigh, shouldn't occur BUT ... */
271 		len = sl->mtu;
272 		printk ("%s: truncating oversized transmit packet!\n", sl->dev->name);
273 		sl->tx_dropped++;
274 		x25_asy_unlock(sl);
275 		return;
276 	}
277 
278 	p = icp;
279 	count = x25_asy_esc(p, (unsigned char *) sl->xbuff, len);
280 
281 	/* Order of next two lines is *very* important.
282 	 * When we are sending a little amount of data,
283 	 * the transfer may be completed inside driver.write()
284 	 * routine, because it's running with interrupts enabled.
285 	 * In this case we *never* got WRITE_WAKEUP event,
286 	 * if we did not request it before write operation.
287 	 *       14 Oct 1994  Dmitry Gorodchanin.
288 	 */
289 	sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
290 	actual = sl->tty->driver.write(sl->tty, 0, sl->xbuff, count);
291 	sl->xleft = count - actual;
292 	sl->xhead = sl->xbuff + actual;
293 	/* VSV */
294 	clear_bit(SLF_OUTWAIT, &sl->flags);	/* reset outfill flag */
295 }
296 
297 /*
298  * Called by the driver when there's room for more data.  If we have
299  * more packets to send, we send them here.
300  */
x25_asy_write_wakeup(struct tty_struct * tty)301 static void x25_asy_write_wakeup(struct tty_struct *tty)
302 {
303 	int actual;
304 	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
305 
306 	/* First make sure we're connected. */
307 	if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
308 		return;
309 
310 	if (sl->xleft <= 0)
311 	{
312 		/* Now serial buffer is almost free & we can start
313 		 * transmission of another packet */
314 		sl->tx_packets++;
315 		tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
316 		x25_asy_unlock(sl);
317 		return;
318 	}
319 
320 	actual = tty->driver.write(tty, 0, sl->xhead, sl->xleft);
321 	sl->xleft -= actual;
322 	sl->xhead += actual;
323 }
324 
x25_asy_timeout(struct net_device * dev)325 static void x25_asy_timeout(struct net_device *dev)
326 {
327 	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
328 	/* May be we must check transmitter timeout here ?
329 	 *      14 Oct 1994 Dmitry Gorodchanin.
330 	 */
331 	printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
332 	       (sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ?
333 	       "bad line quality" : "driver error");
334 	sl->xleft = 0;
335 	sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
336 	x25_asy_unlock(sl);
337 }
338 
339 /* Encapsulate an IP datagram and kick it into a TTY queue. */
340 
x25_asy_xmit(struct sk_buff * skb,struct net_device * dev)341 static int x25_asy_xmit(struct sk_buff *skb, struct net_device *dev)
342 {
343 	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
344 	int err;
345 
346 	if (!netif_running(sl->dev))
347 	{
348 		printk("%s: xmit call when iface is down\n", dev->name);
349 		return 1;
350 	}
351 
352 	switch(skb->data[0])
353 	{
354 		case 0x00:break;
355 		case 0x01: /* Connection request .. do nothing */
356 			if((err=lapb_connect_request(sl))!=LAPB_OK)
357 				printk(KERN_ERR "x25_asy: lapb_connect_request error - %d\n", err);
358 			kfree_skb(skb);
359 			return 0;
360 		case 0x02: /* Disconnect request .. do nothing - hang up ?? */
361 			if((err=lapb_disconnect_request(sl))!=LAPB_OK)
362 				printk(KERN_ERR "x25_asy: lapb_disconnect_request error - %d\n", err);
363 		default:
364 			kfree_skb(skb);
365 			return  0;
366 	}
367 	skb_pull(skb,1);	/* Remove control byte */
368 	/*
369 	 * If we are busy already- too bad.  We ought to be able
370 	 * to queue things at this point, to allow for a little
371 	 * frame buffer.  Oh well...
372 	 * -----------------------------------------------------
373 	 * I hate queues in X.25 driver. May be it's efficient,
374 	 * but for me latency is more important. ;)
375 	 * So, no queues !
376 	 *        14 Oct 1994  Dmitry Gorodchanin.
377 	 */
378 
379 	if((err=lapb_data_request(sl,skb))!=LAPB_OK)
380 	{
381 		printk(KERN_ERR "lapbeth: lapb_data_request error - %d\n", err);
382 		kfree_skb(skb);
383 		return 0;
384 	}
385 	return 0;
386 }
387 
388 
389 /*
390  *	LAPB interface boilerplate
391  */
392 
393 /*
394  *	Called when I frame data arrives. We did the work above - throw it
395  *	at the net layer.
396  */
397 
x25_asy_data_indication(void * token,struct sk_buff * skb)398 static int x25_asy_data_indication(void *token, struct sk_buff *skb)
399 {
400 	return netif_rx(skb);
401 }
402 
403 /*
404  *	Data has emerged from the LAPB protocol machine. We don't handle
405  *	busy cases too well. Its tricky to see how to do this nicely -
406  *	perhaps lapb should allow us to bounce this ?
407  */
408 
x25_asy_data_transmit(void * token,struct sk_buff * skb)409 static void x25_asy_data_transmit(void *token, struct sk_buff *skb)
410 {
411 	struct x25_asy *sl=token;
412 	if (netif_queue_stopped(sl->dev))
413 	{
414 		printk(KERN_ERR "x25_asy: tbusy drop\n");
415 		kfree_skb(skb);
416 		return;
417 	}
418 	/* We were not busy, so we are now... :-) */
419 	if (skb != NULL)
420 	{
421 		x25_asy_lock(sl);
422 		sl->tx_bytes+=skb->len;
423 		x25_asy_encaps(sl, skb->data, skb->len);
424 		dev_kfree_skb(skb);
425 	}
426 }
427 
428 /*
429  *	LAPB connection establish/down information.
430  */
431 
x25_asy_connected(void * token,int reason)432 static void x25_asy_connected(void *token, int reason)
433 {
434 	struct x25_asy *sl = token;
435 	struct sk_buff *skb;
436 	unsigned char *ptr;
437 
438 	if ((skb = dev_alloc_skb(1)) == NULL) {
439 		printk(KERN_ERR "lapbeth: out of memory\n");
440 		return;
441 	}
442 
443 	ptr  = skb_put(skb, 1);
444 	*ptr = 0x01;
445 
446 	skb->dev      = sl->dev;
447 	skb->protocol = htons(ETH_P_X25);
448 	skb->mac.raw  = skb->data;
449 	skb->pkt_type = PACKET_HOST;
450 
451 	netif_rx(skb);
452 }
453 
x25_asy_disconnected(void * token,int reason)454 static void x25_asy_disconnected(void *token, int reason)
455 {
456 	struct x25_asy *sl = token;
457 	struct sk_buff *skb;
458 	unsigned char *ptr;
459 
460 	if ((skb = dev_alloc_skb(1)) == NULL) {
461 		printk(KERN_ERR "x25_asy: out of memory\n");
462 		return;
463 	}
464 
465 	ptr  = skb_put(skb, 1);
466 	*ptr = 0x02;
467 
468 	skb->dev      = sl->dev;
469 	skb->protocol = htons(ETH_P_X25);
470 	skb->mac.raw  = skb->data;
471 	skb->pkt_type = PACKET_HOST;
472 
473 	netif_rx(skb);
474 }
475 
476 
477 /* Open the low-level part of the X.25 channel. Easy! */
478 
x25_asy_open(struct net_device * dev)479 static int x25_asy_open(struct net_device *dev)
480 {
481 	struct lapb_register_struct x25_asy_callbacks;
482 	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
483 	unsigned long len;
484 	int err;
485 
486 	if (sl->tty == NULL)
487 		return -ENODEV;
488 
489 	/*
490 	 * Allocate the X.25 frame buffers:
491 	 *
492 	 * rbuff	Receive buffer.
493 	 * xbuff	Transmit buffer.
494 	 */
495 
496 	len = dev->mtu * 2;
497 
498 	sl->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
499 	if (sl->rbuff == NULL)   {
500 		goto norbuff;
501 	}
502 	sl->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
503 	if (sl->xbuff == NULL)   {
504 		goto noxbuff;
505 	}
506 	sl->mtu	     = dev->mtu;
507 	sl->buffsize = len;
508 	sl->rcount   = 0;
509 	sl->xleft    = 0;
510 	sl->flags   &= (1 << SLF_INUSE);      /* Clear ESCAPE & ERROR flags */
511 
512 	netif_start_queue(dev);
513 
514 	/*
515 	 *	Now attach LAPB
516 	 */
517 
518 	x25_asy_callbacks.connect_confirmation=x25_asy_connected;
519 	x25_asy_callbacks.connect_indication=x25_asy_connected;
520 	x25_asy_callbacks.disconnect_confirmation=x25_asy_disconnected;
521 	x25_asy_callbacks.disconnect_indication=x25_asy_disconnected;
522 	x25_asy_callbacks.data_indication=x25_asy_data_indication;
523 	x25_asy_callbacks.data_transmit=x25_asy_data_transmit;
524 
525 	if((err=lapb_register(sl, &x25_asy_callbacks))==LAPB_OK)
526 		return 0;
527 
528 	/* Cleanup */
529 	kfree(sl->xbuff);
530 noxbuff:
531 	kfree(sl->rbuff);
532 norbuff:
533 	return -ENOMEM;
534 }
535 
536 
537 /* Close the low-level part of the X.25 channel. Easy! */
x25_asy_close(struct net_device * dev)538 static int x25_asy_close(struct net_device *dev)
539 {
540 	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
541 	int err;
542 
543 	if (sl->tty == NULL)
544 		return -EBUSY;
545 
546 	sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
547 	netif_stop_queue(dev);
548 	if((err=lapb_unregister(sl))!=LAPB_OK)
549 		printk(KERN_ERR "x25_asy_close: lapb_unregister error -%d\n",err);
550 	return 0;
551 }
552 
x25_asy_receive_room(struct tty_struct * tty)553 static int x25_asy_receive_room(struct tty_struct *tty)
554 {
555 	return 65536;  /* We can handle an infinite amount of data. :-) */
556 }
557 
558 /*
559  * Handle the 'receiver data ready' interrupt.
560  * This function is called by the 'tty_io' module in the kernel when
561  * a block of X.25 data has been received, which can now be decapsulated
562  * and sent on to some IP layer for further processing.
563  */
564 
x25_asy_receive_buf(struct tty_struct * tty,const unsigned char * cp,char * fp,int count)565 static void x25_asy_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
566 {
567 	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
568 
569 	if (!sl || sl->magic != X25_ASY_MAGIC || !netif_running(sl->dev))
570 		return;
571 
572 	/*
573 	 * Argh! mtu change time! - costs us the packet part received
574 	 * at the change
575 	 */
576 	if (sl->mtu != sl->dev->mtu)  {
577 
578 		x25_asy_changed_mtu(sl);
579 	}
580 
581 	/* Read the characters out of the buffer */
582 	while (count--) {
583 		if (fp && *fp++) {
584 			if (!test_and_set_bit(SLF_ERROR, &sl->flags))  {
585 				sl->rx_errors++;
586 			}
587 			cp++;
588 			continue;
589 		}
590 		x25_asy_unesc(sl, *cp++);
591 	}
592 }
593 
594 /*
595  * Open the high-level part of the X.25 channel.
596  * This function is called by the TTY module when the
597  * X.25 line discipline is called for.  Because we are
598  * sure the tty line exists, we only have to link it to
599  * a free X.25 channel...
600  */
601 
x25_asy_open_tty(struct tty_struct * tty)602 static int x25_asy_open_tty(struct tty_struct *tty)
603 {
604 	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
605 	int err;
606 
607 	/* First make sure we're not already connected. */
608 	if (sl && sl->magic == X25_ASY_MAGIC) {
609 		return -EEXIST;
610 	}
611 
612 	/* OK.  Find a free X.25 channel to use. */
613 	if ((sl = x25_asy_alloc()) == NULL) {
614 		return -ENFILE;
615 	}
616 
617 	sl->tty = tty;
618 	tty->disc_data = sl;
619 	if (tty->driver.flush_buffer)  {
620 		tty->driver.flush_buffer(tty);
621 	}
622 	tty_ldisc_flush(tty);
623 
624 	/* Restore default settings */
625 	sl->dev->type = ARPHRD_X25;
626 
627 	/* Perform the low-level X.25 async init */
628 	if ((err = x25_asy_open(sl->dev)))
629 		return err;
630 
631 	MOD_INC_USE_COUNT;
632 
633 	/* Done.  We have linked the TTY line to a channel. */
634 	return sl->dev->base_addr;
635 }
636 
637 
638 /*
639  * Close down an X.25 channel.
640  * This means flushing out any pending queues, and then restoring the
641  * TTY line discipline to what it was before it got hooked to X.25
642  * (which usually is TTY again).
643  */
x25_asy_close_tty(struct tty_struct * tty)644 static void x25_asy_close_tty(struct tty_struct *tty)
645 {
646 	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
647 
648 	/* First make sure we're connected. */
649 	if (!sl || sl->magic != X25_ASY_MAGIC)
650 		return;
651 
652 	if (sl->dev->flags & IFF_UP)
653 	{
654 		(void) dev_close(sl->dev);
655 	}
656 
657 	tty->disc_data = 0;
658 	sl->tty = NULL;
659 	x25_asy_free(sl);
660 	unregister_netdev(sl->dev);
661 	MOD_DEC_USE_COUNT;
662 }
663 
664 
x25_asy_get_stats(struct net_device * dev)665 static struct net_device_stats *x25_asy_get_stats(struct net_device *dev)
666 {
667 	static struct net_device_stats stats;
668 	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
669 
670 	memset(&stats, 0, sizeof(struct net_device_stats));
671 
672 	stats.rx_packets     = sl->rx_packets;
673 	stats.tx_packets     = sl->tx_packets;
674 	stats.rx_bytes	     = sl->rx_bytes;
675 	stats.tx_bytes	     = sl->tx_bytes;
676 	stats.rx_dropped     = sl->rx_dropped;
677 	stats.tx_dropped     = sl->tx_dropped;
678 	stats.tx_errors      = sl->tx_errors;
679 	stats.rx_errors      = sl->rx_errors;
680 	stats.rx_over_errors = sl->rx_over_errors;
681 	return (&stats);
682 }
683 
684 
685  /************************************************************************
686   *			STANDARD X.25 ENCAPSULATION		  	 *
687   ************************************************************************/
688 
x25_asy_esc(unsigned char * s,unsigned char * d,int len)689 int x25_asy_esc(unsigned char *s, unsigned char *d, int len)
690 {
691 	unsigned char *ptr = d;
692 	unsigned char c;
693 
694 	/*
695 	 * Send an initial END character to flush out any
696 	 * data that may have accumulated in the receiver
697 	 * due to line noise.
698 	 */
699 
700 	*ptr++ = X25_END;	/* Send 10111110 bit seq */
701 
702 	/*
703 	 * For each byte in the packet, send the appropriate
704 	 * character sequence, according to the X.25 protocol.
705 	 */
706 
707 	while (len-- > 0)
708 	{
709 		switch(c = *s++)
710 		{
711 			case X25_END:
712 				*ptr++ = X25_ESC;
713 				*ptr++ = X25_ESCAPE(X25_END);
714 				break;
715 			case X25_ESC:
716 				*ptr++ = X25_ESC;
717 				*ptr++ = X25_ESCAPE(X25_ESC);
718 				break;
719 			 default:
720 				*ptr++ = c;
721 				break;
722 		}
723 	}
724 	*ptr++ = X25_END;
725 	return (ptr - d);
726 }
727 
x25_asy_unesc(struct x25_asy * sl,unsigned char s)728 static void x25_asy_unesc(struct x25_asy *sl, unsigned char s)
729 {
730 
731 	switch(s)
732 	{
733 		case X25_END:
734 			if (!test_and_clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))
735 			{
736 				x25_asy_bump(sl);
737 			}
738 			clear_bit(SLF_ESCAPE, &sl->flags);
739 			sl->rcount = 0;
740 			return;
741 
742 		case X25_ESC:
743 			set_bit(SLF_ESCAPE, &sl->flags);
744 			return;
745 
746 		case X25_ESCAPE(X25_ESC):
747 		case X25_ESCAPE(X25_END):
748 			if (test_and_clear_bit(SLF_ESCAPE, &sl->flags))
749 				s = X25_UNESCAPE(s);
750 			break;
751 	}
752 	if (!test_bit(SLF_ERROR, &sl->flags))
753 	{
754 		if (sl->rcount < sl->buffsize)
755 		{
756 			sl->rbuff[sl->rcount++] = s;
757 			return;
758 		}
759 		sl->rx_over_errors++;
760 		set_bit(SLF_ERROR, &sl->flags);
761 	}
762 }
763 
764 
765 /* Perform I/O control on an active X.25 channel. */
x25_asy_ioctl(struct tty_struct * tty,void * file,int cmd,void * arg)766 static int x25_asy_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
767 {
768 	struct x25_asy *sl = (struct x25_asy *) tty->disc_data;
769 
770 	/* First make sure we're connected. */
771 	if (!sl || sl->magic != X25_ASY_MAGIC) {
772 		return -EINVAL;
773 	}
774 
775 	switch(cmd)
776 	{
777 		case SIOCGIFNAME:
778 			if(copy_to_user(arg, sl->dev->name, strlen(sl->dev->name) + 1))
779 				return -EFAULT;
780 			return 0;
781 
782 		case SIOCSIFHWADDR:
783 			return -EINVAL;
784 
785 		/* Allow stty to read, but not set, the serial port */
786 		case TCGETS:
787 		case TCGETA:
788 			return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg);
789 
790 		default:
791 			return -ENOIOCTLCMD;
792 	}
793 }
794 
x25_asy_open_dev(struct net_device * dev)795 static int x25_asy_open_dev(struct net_device *dev)
796 {
797 	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
798 	if(sl->tty==NULL)
799 		return -ENODEV;
800 	return 0;
801 }
802 
803 /* Initialize X.25 control device -- register X.25 line discipline */
804 
x25_asy_init_ctrl_dev(void)805 int __init x25_asy_init_ctrl_dev(void)
806 {
807 	int status;
808 
809 	if (x25_asy_maxdev < 4) x25_asy_maxdev = 4; /* Sanity */
810 
811 	printk(KERN_INFO "X.25 async: version 0.00 ALPHA (dynamic channels, max=%d).\n",
812 		x25_asy_maxdev );
813 	x25_asy_ctrls = (x25_asy_ctrl_t **) kmalloc(sizeof(void*)*x25_asy_maxdev, GFP_KERNEL);
814 	if (x25_asy_ctrls == NULL)
815 	{
816 		printk("X25 async: Can't allocate x25_asy_ctrls[] array!  Uaargh! (-> No X.25 available)\n");
817 		return -ENOMEM;
818 	}
819 
820 	/* Clear the pointer array, we allocate devices when we need them */
821 	memset(x25_asy_ctrls, 0, sizeof(void*)*x25_asy_maxdev); /* Pointers */
822 
823 	/* Fill in our line protocol discipline, and register it */
824 	memset(&x25_ldisc, 0, sizeof(x25_ldisc));
825 	x25_ldisc.magic  = TTY_LDISC_MAGIC;
826 	x25_ldisc.name   = "X.25";
827 	x25_ldisc.flags  = 0;
828 	x25_ldisc.open   = x25_asy_open_tty;
829 	x25_ldisc.close  = x25_asy_close_tty;
830 	x25_ldisc.read   = NULL;
831 	x25_ldisc.write  = NULL;
832 	x25_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *,
833 				   unsigned int, unsigned long)) x25_asy_ioctl;
834 	x25_ldisc.poll   = NULL;
835 	x25_ldisc.receive_buf = x25_asy_receive_buf;
836 	x25_ldisc.receive_room = x25_asy_receive_room;
837 	x25_ldisc.write_wakeup = x25_asy_write_wakeup;
838 	if ((status = tty_register_ldisc(N_X25, &x25_ldisc)) != 0)  {
839 		printk("X.25 async: can't register line discipline (err = %d)\n", status);
840 	}
841 
842 	return status;
843 }
844 
845 
846 /* Initialise the X.25 driver.  Called by the device init code */
847 
x25_asy_init(struct net_device * dev)848 int x25_asy_init(struct net_device *dev)
849 {
850 	struct x25_asy *sl = (struct x25_asy*)(dev->priv);
851 
852 	if (sl == NULL)		/* Allocation failed ?? */
853 		return -ENODEV;
854 
855 	/* Set up the control block. (And clear statistics) */
856 
857 	memset(sl, 0, sizeof (struct x25_asy));
858 	sl->magic  = X25_ASY_MAGIC;
859 	sl->dev	   = dev;
860 
861 	/*
862 	 *	Finish setting up the DEVICE info.
863 	 */
864 
865 	dev->mtu		= SL_MTU;
866 	dev->hard_start_xmit	= x25_asy_xmit;
867 	dev->tx_timeout		= x25_asy_timeout;
868 	dev->watchdog_timeo	= HZ*20;
869 	dev->open		= x25_asy_open_dev;
870 	dev->stop		= x25_asy_close;
871 	dev->get_stats	        = x25_asy_get_stats;
872 	dev->hard_header_len	= 0;
873 	dev->addr_len		= 0;
874 	dev->type		= ARPHRD_X25;
875 	dev->tx_queue_len	= 10;
876 
877 	/* New-style flags. */
878 	dev->flags		= IFF_NOARP;
879 
880 	return 0;
881 }
882 #ifdef MODULE
883 
884 int
init_module(void)885 init_module(void)
886 {
887 	return x25_asy_init_ctrl_dev();
888 }
889 
890 void
cleanup_module(void)891 cleanup_module(void)
892 {
893 	int i;
894 
895 	if (x25_asy_ctrls != NULL)
896 	{
897 		for (i = 0; i < x25_asy_maxdev; i++)
898 		{
899 			if (x25_asy_ctrls[i])
900 			{
901 				/*
902 				 * VSV = if dev->start==0, then device
903 				 * unregistered while close proc.
904 				 */
905 				if (netif_running(&(x25_asy_ctrls[i]->dev)))
906 					unregister_netdev(&(x25_asy_ctrls[i]->dev));
907 
908 				kfree(x25_asy_ctrls[i]);
909 				x25_asy_ctrls[i] = NULL;
910 			}
911 		}
912 		kfree(x25_asy_ctrls);
913 		x25_asy_ctrls = NULL;
914 	}
915 	if ((i = tty_register_ldisc(N_X25, NULL)))
916 	{
917 		printk("X.25 async: can't unregister line discipline (err = %d)\n", i);
918 	}
919 }
920 #endif /* MODULE */
921 
922