* add p cc
[mascara-docs.git] / i386 / linux / linux-0.99 / drivers / net / slip.c
blob514fa8ceb5eda5b0c5657b425005515b8cffbbb1
1 /*
2 * slip.c This module implements the SLIP protocol for kernel-based
3 * devices like TTY. It interfaces between a raw TTY, and the
4 * kernel's INET protocol layers (via DDI).
6 * Version: @(#)slip.c 0.7.6 05/25/93
8 * Authors: Laurence Culhane, <loz@holmes.demon.co.uk>
9 * Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
11 * Fixes:
12 * Alan Cox : Sanity checks and avoid tx overruns.
13 * Has a new sl->mtu field.
14 * Alan Cox : Found cause of overrun. ifconfig sl0 mtu upwards.
15 * Driver now spots this and grows/shrinks its buffers(hack!).
16 * Memory leak if you run out of memory setting up a slip driver fixed.
17 * Matt Dillon : Printable slip (borrowed from NET2E)
18 * Pauline Middelink : Slip driver fixes.
19 * Alan Cox : Honours the old SL_COMPRESSED flag
20 * Alan Cox : KISS AX.25 and AXUI IP support
21 * Michael Riepe : Automatic CSLIP recognition added
24 #include <asm/segment.h>
25 #include <asm/system.h>
27 #include <linux/config.h>
28 #include <linux/types.h>
29 #include <linux/kernel.h>
30 #include <linux/sched.h>
31 #include <linux/string.h>
32 #include <linux/mm.h>
33 #include <linux/socket.h>
34 #include <linux/sockios.h>
35 #include <linux/interrupt.h>
36 #include <linux/tty.h>
37 #include <linux/errno.h>
38 #include <linux/stat.h>
39 #include <linux/in.h>
40 #include "inet.h"
41 #include "dev.h"
42 #ifdef CONFIG_AX25
43 #include "ax25.h"
44 #endif
45 #include "eth.h"
46 #include "ip.h"
47 #include "route.h"
48 #include "protocol.h"
49 #include "tcp.h"
50 #include "skbuff.h"
51 #include "sock.h"
52 #include "arp.h"
53 #include "slip.h"
54 #include "slhc.h"
56 #define SLIP_VERSION "0.7.5"
58 /* Define some IP layer stuff. Not all systems have it. */
59 #ifdef SL_DUMP
60 # define IP_VERSION 4 /* version# of our IP software */
61 # define IPF_F_OFFSET 0x1fff /* Offset field */
62 # define IPF_DF 0x4000 /* Don't fragment flag */
63 # define IPF_MF 0x2000 /* More Fragments flag */
64 # define IP_OF_COPIED 0x80 /* Copied-on-fragmentation flag */
65 # define IP_OF_CLASS 0x60 /* Option class */
66 # define IP_OF_NUMBER 0x1f /* Option number */
67 #endif
70 static struct slip sl_ctrl[SL_NRUNIT];
71 static struct tty_ldisc sl_ldisc;
72 static int already = 0;
75 /* Dump the contents of an IP datagram. */
76 static void
77 ip_dump(unsigned char *ptr, int len)
79 #ifdef SL_DUMP
80 struct iphdr *ip;
81 struct tcphdr *th;
82 int dlen, doff;
84 if (inet_debug != DBG_SLIP) return;
86 ip = (struct iphdr *) ptr;
87 th = (struct tcphdr *) (ptr + ip->ihl * 4);
88 printk("\r%s -> %s seq %lx ack %lx len %d\n",
89 in_ntoa(ip->saddr), in_ntoa(ip->daddr),
90 ntohl(th->seq), ntohl(th->ack_seq), ntohs(ip->tot_len));
91 return;
93 printk("\r*****\n");
94 printk("%p %d\n", ptr, len);
95 ip = (struct iphdr *) ptr;
96 dlen = ntohs(ip->tot_len);
97 doff = ((ntohs(ip->frag_off) & IPF_F_OFFSET) << 3);
100 printk("SLIP: %s->", in_ntoa(ip->saddr));
101 printk("%s\n", in_ntoa(ip->daddr));
102 printk(" len %u ihl %u ver %u ttl %u prot %u",
103 dlen, ip->ihl, ip->version, ip->ttl, ip->protocol);
105 if (ip->tos != 0) printk(" tos %u", ip->tos);
106 if (doff != 0 || (ntohs(ip->frag_off) & IPF_MF))
107 printk(" id %u offs %u", ntohs(ip->id), doff);
109 if (ntohs(ip->frag_off) & IPF_DF) printk(" DF");
110 if (ntohs(ip->frag_off) & IPF_MF) printk(" MF");
111 printk("\n*****\n");
112 #endif
115 #if 0
116 void clh_dump(unsigned char *cp, int len)
118 if (len > 60)
119 len = 60;
120 printk("%d:", len);
121 while (len > 0) {
122 printk(" %x", *cp++);
123 len--;
125 printk("\n\n");
127 #endif
129 /* Initialize a SLIP control block for use. */
130 static void
131 sl_initialize(struct slip *sl, struct device *dev)
133 sl->inuse = 0;
134 sl->sending = 0;
135 sl->escape = 0;
136 sl->flags = 0;
137 #ifdef SL_ADAPTIVE
138 sl->mode = SL_MODE_ADAPTIVE; /* automatic CSLIP recognition */
139 #else
140 #ifdef SL_COMPRESSED
141 sl->mode = SL_MODE_CSLIP | SL_MODE_ADAPTIVE; /* Default */
142 #else
143 sl->mode = SL_MODE_SLIP; /* Default for non compressors */
144 #endif
145 #endif
147 sl->line = dev->base_addr;
148 sl->tty = NULL;
149 sl->dev = dev;
150 sl->slcomp = NULL;
152 /* Clear all pointers. */
153 sl->rbuff = NULL;
154 sl->xbuff = NULL;
155 sl->cbuff = NULL;
157 sl->rhead = NULL;
158 sl->rend = NULL;
159 dev->rmem_end = (unsigned long) NULL;
160 dev->rmem_start = (unsigned long) NULL;
161 dev->mem_end = (unsigned long) NULL;
162 dev->mem_start = (unsigned long) NULL;
166 /* Find a SLIP channel from its `tty' link. */
167 static struct slip *
168 sl_find(struct tty_struct *tty)
170 struct slip *sl;
171 int i;
173 if (tty == NULL) return(NULL);
174 for (i = 0; i < SL_NRUNIT; i++) {
175 sl = &sl_ctrl[i];
176 if (sl->tty == tty) return(sl);
178 return(NULL);
182 /* Find a free SLIP channel, and link in this `tty' line. */
183 static inline struct slip *
184 sl_alloc(void)
186 unsigned long flags;
187 struct slip *sl;
188 int i;
190 save_flags (flags);
191 cli();
192 for (i = 0; i < SL_NRUNIT; i++) {
193 sl = &sl_ctrl[i];
194 if (sl->inuse == 0) {
195 sl->inuse = 1;
196 sl->tty = NULL;
197 restore_flags(flags);
198 return(sl);
201 restore_flags(flags);
202 return(NULL);
206 /* Free a SLIP channel. */
207 static inline void
208 sl_free(struct slip *sl)
210 unsigned long flags;
212 if (sl->inuse) {
213 save_flags(flags);
214 cli();
215 sl->inuse = 0;
216 sl->tty = NULL;
217 restore_flags(flags);
221 /* MTU has been changed by the IP layer. Unfortunately we are not told about this, but
222 we spot it ourselves and fix things up. We could be in an upcall from the tty
223 driver, or in an ip packet queue. */
225 static void sl_changedmtu(struct slip *sl)
227 struct device *dev=sl->dev;
228 unsigned char *tb,*rb,*cb,*tf,*rf,*cf;
229 int l;
230 int omtu=sl->mtu;
232 sl->mtu=dev->mtu;
233 l=(dev->mtu *2);
235 DPRINTF((DBG_SLIP,"SLIP: mtu changed!\n"));
237 tb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
238 rb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
239 cb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
241 if(tb==NULL || rb==NULL || cb==NULL)
243 printk("Unable to grow slip buffers. MTU change cancelled.\n");
244 sl->mtu=omtu;
245 dev->mtu=omtu;
246 if(tb!=NULL)
247 kfree(tb);
248 if(rb!=NULL)
249 kfree(rb);
250 if(cb!=NULL)
251 kfree(cb);
252 return;
255 cli();
257 tf=(unsigned char *)sl->dev->mem_start;
258 sl->dev->mem_start=(unsigned long)tb;
259 sl->dev->mem_end=(unsigned long) (sl->dev->mem_start + l);
260 rf=(unsigned char *)sl->dev->rmem_start;
261 sl->dev->rmem_start=(unsigned long)rb;
262 sl->dev->rmem_end=(unsigned long) (sl->dev->rmem_start + l);
264 sl->xbuff = (unsigned char *) sl->dev->mem_start;
265 sl->rbuff = (unsigned char *) sl->dev->rmem_start;
266 sl->rend = (unsigned char *) sl->dev->rmem_end;
267 sl->rhead = sl->rbuff;
269 cf=sl->cbuff;
270 sl->cbuff=cb;
272 sl->escape=0;
273 sl->sending=0;
274 sl->rcount=0;
276 sti();
278 if(rf!=NULL)
279 kfree(rf);
280 if(tf!=NULL)
281 kfree(tf);
282 if(cf!=NULL)
283 kfree(cf);
287 /* Stuff one byte into a SLIP receiver buffer. */
288 static inline void
289 sl_enqueue(struct slip *sl, unsigned char c)
291 unsigned long flags;
293 save_flags(flags);
294 cli();
295 if (sl->rhead < sl->rend) {
296 *sl->rhead = c;
297 sl->rhead++;
298 sl->rcount++;
299 } else sl->roverrun++;
300 restore_flags(flags);
303 /* Release 'i' bytes from a SLIP receiver buffer. */
304 static inline void
305 sl_dequeue(struct slip *sl, int i)
307 unsigned long flags;
309 save_flags(flags);
310 cli();
311 if (sl->rhead > sl->rbuff) {
312 sl->rhead -= i;
313 sl->rcount -= i;
315 restore_flags(flags);
319 /* Set the "sending" flag. This must be atomic, hence the ASM. */
320 static inline void
321 sl_lock(struct slip *sl)
323 unsigned long flags;
325 save_flags(flags);
326 cli();
327 sl->sending = 1;
328 sl->dev->tbusy = 1;
329 restore_flags(flags);
333 /* Clear the "sending" flag. This must be atomic, hence the ASM. */
334 static inline void
335 sl_unlock(struct slip *sl)
337 unsigned long flags;
339 save_flags(flags);
340 cli();
341 sl->sending = 0;
342 sl->dev->tbusy = 0;
343 restore_flags(flags);
347 /* Send one completely decapsulated IP datagram to the IP layer. */
348 static void
349 sl_bump(struct slip *sl)
351 int done;
352 unsigned char c;
353 unsigned long flags;
354 int count;
356 count = sl->rcount;
357 if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
358 if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
359 #if 1
360 /* ignore compressed packets when CSLIP is off */
361 if (!(sl->mode & SL_MODE_CSLIP)) {
362 printk("SLIP: compressed packet ignored\n");
363 return;
365 #endif
366 /* make sure we've reserved enough space for uncompress to use */
367 save_flags(flags);
368 cli();
369 if ((sl->rhead + 80) < sl->rend) {
370 sl->rhead += 80;
371 sl->rcount += 80;
372 done = 1;
373 } else {
374 sl->roverrun++;
375 done = 0;
377 restore_flags(flags);
378 if (! done) /* not enough space available */
379 return;
381 count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
382 if (count <= 0) {
383 sl->errors++;
384 return;
386 } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
387 if (!(sl->mode & SL_MODE_CSLIP)) {
388 /* turn on header compression */
389 sl->mode |= SL_MODE_CSLIP;
390 printk("SLIP: header compression turned on\n");
392 sl->rbuff[0] &= 0x4f;
393 if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
394 sl->errors++;
395 return;
400 DPRINTF((DBG_SLIP, "<< \"%s\" recv:\r\n", sl->dev->name));
401 ip_dump(sl->rbuff, sl->rcount);
403 /* Bump the datagram to the upper layers... */
404 do {
405 DPRINTF((DBG_SLIP, "SLIP: packet is %d at 0x%X\n",
406 sl->rcount, sl->rbuff));
407 /* clh_dump(sl->rbuff, count); */
408 done = dev_rint(sl->rbuff, count, 0, sl->dev);
409 if (done == 0 || done == 1) break;
410 } while(1);
412 sl->rpacket++;
416 /* TTY finished sending a datagram, so clean up. */
417 static void
418 sl_next(struct slip *sl)
420 DPRINTF((DBG_SLIP, "SLIP: sl_next(0x%X) called!\n", sl));
421 sl_unlock(sl);
422 dev_tint(sl->dev);
426 /* Encapsulate one IP datagram and stuff into a TTY queue. */
427 static void
428 sl_encaps(struct slip *sl, unsigned char *icp, int len)
430 unsigned char *bp, *p;
431 int count;
433 DPRINTF((DBG_SLIP, "SLIP: sl_encaps(0x%X, %d) called\n", icp, len));
434 DPRINTF((DBG_SLIP, ">> \"%s\" sent:\r\n", sl->dev->name));
436 ip_dump(icp, len);
438 if(sl->mtu != sl->dev->mtu) /* Someone has been ifconfigging */
439 sl_changedmtu(sl);
441 if(len>sl->mtu) /* Sigh, shouldn't occur BUT ... */
443 len=sl->mtu;
444 printk("slip: truncating oversized transmit packet!\n");
447 p = icp;
448 if(sl->mode & SL_MODE_CSLIP)
449 len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
451 #ifdef OLD
453 * Send an initial END character to flush out any
454 * data that may have accumulated in the receiver
455 * due to line noise.
457 bp = sl->xbuff;
458 *bp++ = END;
459 count = 1;
462 * For each byte in the packet, send the appropriate
463 * character sequence, according to the SLIP protocol.
465 while(len-- > 0) {
466 c = *p++;
467 switch(c) {
468 case END:
469 *bp++ = ESC;
470 *bp++ = ESC_END;
471 count += 2;
472 break;
473 case ESC:
474 *bp++ = ESC;
475 *bp++ = ESC_ESC;
476 count += 2;
477 break;
478 default:
479 *bp++ = c;
480 count++;
483 *bp++ = END;
484 count++;
485 #else
486 if(sl->mode & SL_MODE_SLIP6)
487 count=slip_esc6(p, (unsigned char *)sl->xbuff,len);
488 else
489 count=slip_esc(p, (unsigned char *)sl->xbuff,len);
490 #endif
491 sl->spacket++;
492 bp = sl->xbuff;
494 /* Tell TTY to send it on its way. */
495 DPRINTF((DBG_SLIP, "SLIP: kicking TTY for %d bytes at 0x%X\n", count, bp));
496 if (tty_write_data(sl->tty, (char *) bp, count,
497 (void (*)(void *))sl_next, (void *) sl) == 0) {
498 DPRINTF((DBG_SLIP, "SLIP: TTY already done with %d bytes!\n", count));
499 sl_next(sl);
503 /*static void sl_hex_dump(unsigned char *x,int l)
505 int n=0;
506 printk("sl_xmit: (%d bytes)\n",l);
507 while(l)
509 printk("%2X ",(int)*x++);
510 l--;
511 n++;
512 if(n%32==0)
513 printk("\n");
515 if(n%32)
516 printk("\n");
519 /* Encapsulate an IP datagram and kick it into a TTY queue. */
520 static int
521 sl_xmit(struct sk_buff *skb, struct device *dev)
523 struct tty_struct *tty;
524 struct slip *sl;
526 /* Find the correct SLIP channel to use. */
527 sl = &sl_ctrl[dev->base_addr];
528 tty = sl->tty;
529 DPRINTF((DBG_SLIP, "SLIP: sl_xmit(\"%s\") skb=0x%X busy=%d\n",
530 dev->name, skb, sl->sending));
533 * If we are busy already- too bad. We ought to be able
534 * to queue things at this point, to allow for a little
535 * frame buffer. Oh well...
537 if (sl->sending) {
538 DPRINTF((DBG_SLIP, "SLIP: sl_xmit: BUSY\r\n"));
539 sl->sbusy++;
540 return(1);
543 /* We were not, so we are now... :-) */
544 if (skb != NULL) {
545 #ifdef CONFIG_AX25
546 if(sl->mode & SL_MODE_AX25)
548 if(!skb->arp && dev->rebuild_header(skb->data,dev))
550 skb->dev=dev;
551 arp_queue(skb);
552 return 0;
554 skb->arp=1;
556 #endif
557 sl_lock(sl);
558 /* sl_hex_dump(skb->data,skb->len);*/
559 sl_encaps(sl, skb->data, skb->len);
560 if (skb->free) kfree_skb(skb, FREE_WRITE);
562 return(0);
566 /* Return the frame type ID. This is normally IP but maybe be AX.25. */
567 static unsigned short
568 sl_type_trans (struct sk_buff *skb, struct device *dev)
570 #ifdef CONFIG_AX25
571 struct slip *sl=&sl_ctrl[dev->base_addr];
572 if(sl->mode&SL_MODE_AX25)
573 return(NET16(ETH_P_AX25));
574 #endif
575 return(NET16(ETH_P_IP));
579 /* Fill in the MAC-level header. Not used by SLIP. */
580 static int
581 sl_header(unsigned char *buff, struct device *dev, unsigned short type,
582 unsigned long daddr, unsigned long saddr, unsigned len)
584 #ifdef CONFIG_AX25
585 struct slip *sl=&sl_ctrl[dev->base_addr];
586 if((sl->mode&SL_MODE_AX25) && type!=NET16(ETH_P_AX25))
587 return ax25_encapsulate_ip(buff,dev,type,daddr,saddr,len);
588 #endif
590 return(0);
594 /* Add an ARP-entry for this device's broadcast address. Not used. */
595 static void
596 sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
598 #ifdef CONFIG_AX25
599 struct slip *sl=&sl_ctrl[dev->base_addr];
601 if(sl->mode&SL_MODE_AX25)
602 arp_add(addr,((char *) skb->data)+8,dev);
603 #endif
607 /* Rebuild the MAC-level header. Not used by SLIP. */
608 static int
609 sl_rebuild_header(void *buff, struct device *dev)
611 #ifdef CONFIG_AX25
612 struct slip *sl=&sl_ctrl[dev->base_addr];
614 if(sl->mode&SL_MODE_AX25)
615 return ax25_rebuild_header(buff,dev);
616 #endif
617 return(0);
621 /* Open the low-level part of the SLIP channel. Easy! */
622 static int
623 sl_open(struct device *dev)
625 struct slip *sl;
626 unsigned char *p;
627 unsigned long l;
629 sl = &sl_ctrl[dev->base_addr];
630 if (sl->tty == NULL) {
631 DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
632 return(-ENXIO);
634 sl->dev = dev;
637 * Allocate the SLIP frame buffers:
639 * mem_end Top of frame buffers
640 * mem_start Start of frame buffers
641 * rmem_end Top of RECV frame buffer
642 * rmem_start Start of RECV frame buffer
644 l = (dev->mtu * 2);
645 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
646 if (p == NULL) {
647 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP XMIT buffer!\n"));
648 return(-ENOMEM);
651 sl->mtu = dev->mtu;
652 sl->dev->mem_start = (unsigned long) p;
653 sl->dev->mem_end = (unsigned long) (sl->dev->mem_start + l);
655 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
656 if (p == NULL) {
657 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP RECV buffer!\n"));
658 return(-ENOMEM);
660 sl->dev->rmem_start = (unsigned long) p;
661 sl->dev->rmem_end = (unsigned long) (sl->dev->rmem_start + l);
663 sl->xbuff = (unsigned char *) sl->dev->mem_start;
664 sl->rbuff = (unsigned char *) sl->dev->rmem_start;
665 sl->rend = (unsigned char *) sl->dev->rmem_end;
666 sl->rhead = sl->rbuff;
668 sl->escape = 0;
669 sl->sending = 0;
670 sl->rcount = 0;
672 p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
673 if (p == NULL) {
674 kfree((unsigned char *)sl->dev->mem_start);
675 DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP COMPRESS buffer!\n"));
676 return(-ENOMEM);
678 sl->cbuff = p;
680 sl->slcomp = slhc_init(16, 16);
681 if (sl->slcomp == NULL) {
682 kfree((unsigned char *)sl->dev->mem_start);
683 kfree((unsigned char *)sl->dev->rmem_start);
684 kfree(sl->cbuff);
685 DPRINTF((DBG_SLIP, "SLIP: no memory for SLCOMP!\n"));
686 return(-ENOMEM);
689 dev->flags|=IFF_UP;
690 /* Needed because address '0' is special */
691 if(dev->pa_addr==0)
692 dev->pa_addr=ntohl(0xC0000001);
693 DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
694 return(0);
698 /* Close the low-level part of the SLIP channel. Easy! */
699 static int
700 sl_close(struct device *dev)
702 struct slip *sl;
704 sl = &sl_ctrl[dev->base_addr];
705 if (sl->tty == NULL) {
706 DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
707 return(-EBUSY);
709 sl_free(sl);
711 /* Free all SLIP frame buffers. */
712 kfree(sl->rbuff);
713 kfree(sl->xbuff);
714 kfree(sl->cbuff);
715 slhc_free(sl->slcomp);
717 sl_initialize(sl, dev);
719 DPRINTF((DBG_SLIP, "SLIP: channel %d closed.\n", sl->line));
720 return(0);
725 * Handle the 'receiver data ready' interrupt.
726 * This function is called by the 'tty_io' module in the kernel when
727 * a block of SLIP data has been received, which can now be decapsulated
728 * and sent on to some IP layer for further processing.
730 static void
731 slip_recv(struct tty_struct *tty)
733 unsigned char buff[128];
734 unsigned char *p;
735 struct slip *sl;
736 int count, error=0;
738 DPRINTF((DBG_SLIP, "SLIP: slip_recv(%d) called\n", tty->line));
739 if ((sl = sl_find(tty)) == NULL) return; /* not connected */
741 if(sl->mtu!=sl->dev->mtu) /* Argh! mtu change time! - costs us the packet part received at the change */
742 sl_changedmtu(sl);
744 /* Suck the bytes out of the TTY queues. */
745 do {
746 count = tty_read_raw_data(tty, buff, 128);
747 if (count <= 0)
749 count= - count;
750 if(count)
751 error=1;
752 break;
754 p = buff;
755 #ifdef OLD
756 while (count--) {
757 c = *p++;
758 if (sl->escape) {
759 if (c == ESC_ESC)
760 sl_enqueue(sl, ESC);
761 else if (c == ESC_END)
762 sl_enqueue(sl, END);
763 else
764 printk ("SLIP: received wrong character\n");
765 sl->escape = 0;
766 } else {
767 if (c == ESC)
768 sl->escape = 1;
769 else if (c == END) {
770 if (sl->rcount > 2) sl_bump(sl);
771 sl_dequeue(sl, sl->rcount);
772 sl->rcount = 0;
773 } else sl_enqueue(sl, c);
776 #else
777 if(sl->mode & SL_MODE_SLIP6)
778 slip_unesc6(sl,buff,count,error);
779 else
780 slip_unesc(sl,buff,count,error);
781 #endif
782 } while(1);
788 * Open the high-level part of the SLIP channel.
789 * This function is called by the TTY module when the
790 * SLIP line discipline is called for. Because we are
791 * sure the tty line exists, we only have to link it to
792 * a free SLIP channel...
794 static int
795 slip_open(struct tty_struct *tty)
797 struct slip *sl;
799 /* First make sure we're not already connected. */
800 if ((sl = sl_find(tty)) != NULL) {
801 DPRINTF((DBG_SLIP, "SLIP: TTY %d already connected to %s !\n",
802 tty->line, sl->dev->name));
803 return(-EEXIST);
806 /* OK. Find a free SLIP channel to use. */
807 if ((sl = sl_alloc()) == NULL) {
808 DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected: all channels in use!\n",
809 tty->line));
810 return(-ENFILE);
812 sl->tty = tty;
813 tty_read_flush(tty);
814 tty_write_flush(tty);
816 /* Perform the low-level SLIP initialization. */
817 (void) sl_open(sl->dev);
818 DPRINTF((DBG_SLIP, "SLIP: TTY %d connected to %s.\n",
819 tty->line, sl->dev->name));
821 /* Done. We have linked the TTY line to a channel. */
822 return(sl->line);
826 static struct enet_statistics *
827 sl_get_stats(struct device *dev)
829 static struct enet_statistics stats;
830 struct slip *sl;
831 struct slcompress *comp;
833 /* Find the correct SLIP channel to use. */
834 sl = &sl_ctrl[dev->base_addr];
835 if (! sl)
836 return NULL;
838 memset(&stats, 0, sizeof(struct enet_statistics));
840 stats.rx_packets = sl->rpacket;
841 stats.rx_over_errors = sl->roverrun;
842 stats.tx_packets = sl->spacket;
843 stats.tx_dropped = sl->sbusy;
844 stats.rx_errors = sl->errors;
846 comp = sl->slcomp;
847 if (comp) {
848 stats.rx_fifo_errors = comp->sls_i_compressed;
849 stats.rx_dropped = comp->sls_i_tossed;
850 stats.tx_fifo_errors = comp->sls_o_compressed;
851 stats.collisions = comp->sls_o_misses;
854 return (&stats);
858 * Close down a SLIP channel.
859 * This means flushing out any pending queues, and then restoring the
860 * TTY line discipline to what it was before it got hooked to SLIP
861 * (which usually is TTY again).
863 static void
864 slip_close(struct tty_struct *tty)
866 struct slip *sl;
868 /* First make sure we're connected. */
869 if ((sl = sl_find(tty)) == NULL) {
870 DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected !\n", tty->line));
871 return;
874 (void) dev_close(sl->dev);
875 DPRINTF((DBG_SLIP, "SLIP: TTY %d disconnected from %s.\n",
876 tty->line, sl->dev->name));
880 /************************************************************************
881 * STANDARD SLIP ENCAPSULATION *
882 ************************************************************************
887 slip_esc(unsigned char *s, unsigned char *d, int len)
889 int count = 0;
892 * Send an initial END character to flush out any
893 * data that may have accumulated in the receiver
894 * due to line noise.
897 d[count++] = END;
900 * For each byte in the packet, send the appropriate
901 * character sequence, according to the SLIP protocol.
904 while(len-- > 0) {
905 switch(*s) {
906 case END:
907 d[count++] = ESC;
908 d[count++] = ESC_END;
909 break;
910 case ESC:
911 d[count++] = ESC;
912 d[count++] = ESC_ESC;
913 break;
914 default:
915 d[count++] = *s;
917 ++s;
919 d[count++] = END;
920 return(count);
923 void
924 slip_unesc(struct slip *sl, unsigned char *s, int count, int error)
926 int i;
928 for (i = 0; i < count; ++i, ++s) {
929 switch(*s) {
930 case ESC:
931 sl->flags |= SLF_ESCAPE;
932 break;
933 case ESC_ESC:
934 if (sl->flags & SLF_ESCAPE)
935 sl_enqueue(sl, ESC);
936 else
937 sl_enqueue(sl, *s);
938 sl->flags &= ~SLF_ESCAPE;
939 break;
940 case ESC_END:
941 if (sl->flags & SLF_ESCAPE)
942 sl_enqueue(sl, END);
943 else
944 sl_enqueue(sl, *s);
945 sl->flags &= ~SLF_ESCAPE;
946 break;
947 case END:
948 if (sl->rcount > 2)
949 sl_bump(sl);
950 sl_dequeue(sl, sl->rcount);
951 sl->rcount = 0;
952 sl->flags &= ~(SLF_ESCAPE | SLF_ERROR);
953 break;
954 default:
955 sl_enqueue(sl, *s);
956 sl->flags &= ~SLF_ESCAPE;
959 if (error)
960 sl->flags |= SLF_ERROR;
963 /************************************************************************
964 * 6 BIT SLIP ENCAPSULATION *
965 ************************************************************************
970 slip_esc6(unsigned char *s, unsigned char *d, int len)
972 int count = 0;
973 int i;
974 unsigned short v = 0;
975 short bits = 0;
978 * Send an initial END character to flush out any
979 * data that may have accumulated in the receiver
980 * due to line noise.
983 d[count++] = 0x70;
986 * Encode the packet into printable ascii characters
989 for (i = 0; i < len; ++i) {
990 v = (v << 8) | s[i];
991 bits += 8;
992 while (bits >= 6) {
993 unsigned char c;
995 bits -= 6;
996 c = 0x30 + ((v >> bits) & 0x3F);
997 d[count++] = c;
1000 if (bits) {
1001 unsigned char c;
1003 c = 0x30 + ((v << (6 - bits)) & 0x3F);
1004 d[count++] = c;
1006 d[count++] = 0x70;
1007 return(count);
1010 void
1011 slip_unesc6(struct slip *sl, unsigned char *s, int count, int error)
1013 int i;
1014 unsigned char c;
1016 for (i = 0; i < count; ++i, ++s) {
1017 if (*s == 0x70) {
1018 if (sl->rcount > 8) { /* XXX must be 2 for compressed slip */
1019 #ifdef NOTDEF
1020 printk("rbuff %02x %02x %02x %02x\n",
1021 sl->rbuff[0],
1022 sl->rbuff[1],
1023 sl->rbuff[2],
1024 sl->rbuff[3]
1026 #endif
1027 sl_bump(sl);
1029 sl_dequeue(sl, sl->rcount);
1030 sl->rcount = 0;
1031 sl->flags &= ~(SLF_ESCAPE | SLF_ERROR); /* SLF_ESCAPE not used */
1032 sl->xbits = 0;
1033 } else if (*s >= 0x30 && *s < 0x70) {
1034 sl->xdata = (sl->xdata << 6) | ((*s - 0x30) & 0x3F);
1035 sl->xbits += 6;
1036 if (sl->xbits >= 8) {
1037 sl->xbits -= 8;
1038 c = (unsigned char)(sl->xdata >> sl->xbits);
1039 sl_enqueue(sl, c);
1044 if (error)
1045 sl->flags |= SLF_ERROR;
1049 #ifdef CONFIG_AX25
1051 int sl_set_mac_address(struct device *dev, void *addr)
1053 int err=verify_area(VERIFY_READ,addr,7);
1054 if(err)
1055 return err;
1056 memcpy_fromfs(dev->dev_addr,addr,7); /* addr is an AX.25 shifted ASCII mac address */
1057 return 0;
1059 #endif
1062 /* Perform I/O control on an active SLIP channel. */
1063 static int
1064 slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
1066 struct slip *sl;
1067 int err;
1069 /* First make sure we're connected. */
1070 if ((sl = sl_find(tty)) == NULL) {
1071 DPRINTF((DBG_SLIP, "SLIP: ioctl: TTY %d not connected !\n", tty->line));
1072 return(-EINVAL);
1075 DPRINTF((DBG_SLIP, "SLIP: ioctl(%d, 0x%X, 0x%X)\n", tty->line, cmd, arg));
1076 switch(cmd) {
1077 case SIOCGIFNAME:
1078 err=verify_area(VERIFY_WRITE, arg, 16);
1079 if(err)
1080 return -err;
1081 memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
1082 return(0);
1083 case SIOCGIFENCAP:
1084 err=verify_area(VERIFY_WRITE,arg,sizeof(long));
1085 put_fs_long(sl->mode,(long *)arg);
1086 return(0);
1087 case SIOCSIFENCAP:
1088 err=verify_area(VERIFY_READ,arg,sizeof(long));
1089 sl->mode=get_fs_long((long *)arg);
1090 #ifdef CONFIG_AX25
1091 if(sl->mode & SL_MODE_AX25)
1093 sl->dev->addr_len=7; /* sizeof an AX.25 addr */
1094 sl->dev->hard_header_len=17; /* We don't do digipeaters */
1095 sl->dev->type=3; /* AF_AX25 not an AF_INET device */
1097 else
1099 sl->dev->addr_len=0; /* No mac addr in slip mode */
1100 sl->dev->hard_header_len=0;
1101 sl->dev->type=0;
1103 #endif
1104 return(0);
1105 case SIOCSIFHWADDR:
1106 #ifdef CONFIG_AX25
1107 return sl_set_mac_address(sl->dev,arg);
1108 #endif
1109 default:
1110 return(-EINVAL);
1112 return(-EINVAL);
1116 /* Initialize the SLIP driver. Called by DDI. */
1118 slip_init(struct device *dev)
1120 struct slip *sl;
1121 int i;
1122 #ifdef CONFIG_AX25
1123 static char ax25_bcast[7]={'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
1124 static char ax25_test[7]={'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
1125 #endif
1127 sl = &sl_ctrl[dev->base_addr];
1129 if (already++ == 0) {
1130 printk("SLIP: version %s (%d channels)\n",
1131 SLIP_VERSION, SL_NRUNIT);
1132 printk("CSLIP: code copyright 1989 Regents of the University of California\n");
1133 #ifdef CONFIG_AX25
1134 printk("AX25: KISS encapsulation enabled\n");
1135 #endif
1136 /* Fill in our LDISC request block. */
1137 sl_ldisc.flags = 0;
1138 sl_ldisc.open = slip_open;
1139 sl_ldisc.close = slip_close;
1140 sl_ldisc.read = NULL;
1141 sl_ldisc.write = NULL;
1142 sl_ldisc.ioctl = (int (*)(struct tty_struct *, struct file *,
1143 unsigned int, unsigned long)) slip_ioctl;
1144 sl_ldisc.select = NULL;
1145 sl_ldisc.handler = slip_recv;
1146 if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
1147 printk("ERROR: %d\n", i);
1150 /* Set up the "SLIP Control Block". */
1151 sl_initialize(sl, dev);
1153 /* Clear all statistics. */
1154 sl->rcount = 0; /* SLIP receiver count */
1155 sl->rpacket = 0; /* #frames received */
1156 sl->roverrun = 0; /* "overrun" counter */
1157 sl->spacket = 0; /* #frames sent out */
1158 sl->sbusy = 0; /* "xmit busy" counter */
1159 sl->errors = 0; /* not used at present */
1161 /* Finish setting up the DEVICE info. */
1162 dev->mtu = SL_MTU;
1163 dev->hard_start_xmit = sl_xmit;
1164 dev->open = sl_open;
1165 dev->stop = sl_close;
1166 dev->hard_header = sl_header;
1167 dev->add_arp = sl_add_arp;
1168 dev->type_trans = sl_type_trans;
1169 dev->get_stats = sl_get_stats;
1170 #ifdef HAVE_SET_MAC_ADDR
1171 #ifdef CONFIG_AX25
1172 dev->set_mac_address = sl_set_mac_address;
1173 #endif
1174 #endif
1175 dev->hard_header_len = 0;
1176 dev->addr_len = 0;
1177 dev->type = 0;
1178 #ifdef CONFIG_AX25
1179 memcpy(dev->broadcast,ax25_bcast,7); /* Only activated in AX.25 mode */
1180 memcpy(dev->dev_addr,ax25_test,7); /* "" "" "" "" */
1181 #endif
1182 dev->queue_xmit = dev_queue_xmit;
1183 dev->rebuild_header = sl_rebuild_header;
1184 for (i = 0; i < DEV_NUMBUFFS; i++)
1185 dev->buffs[i] = NULL;
1187 /* New-style flags. */
1188 dev->flags = 0;
1189 dev->family = AF_INET;
1190 dev->pa_addr = 0;
1191 dev->pa_brdaddr = 0;
1192 dev->pa_mask = 0;
1193 dev->pa_alen = sizeof(unsigned long);
1195 return(0);