/*
 * slip.c	This module implements the SLIP protocol for kernel-based
 *		devices like TTY.  It interfaces between a raw TTY, and the
 *		kernel's INET protocol layers (via DDI).
 *
 * Version:	@(#)slip.c	0.7.6	05/25/93
 *
 * Authors:	Laurence Culhane, <loz@holmes.demon.co.uk>
 *		Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
 *
 * Fixes:
 *		Alan Cox	: 	Sanity checks and avoid tx overruns.
 *					Has a new sl->mtu field.
 *		Alan Cox	: 	Found cause of overrun. ifconfig sl0 mtu upwards.
 *					Driver now spots this and grows/shrinks its buffers(hack!).
 *					Memory leak if you run out of memory setting up a slip driver fixed.
 *		Matt Dillon	:	Printable slip (borrowed from NET2E)
 *	Pauline Middelink	:	Slip driver fixes.
 *		Alan Cox	:	Honours the old SL_COMPRESSED flag
 *		Alan Cox	:	KISS AX.25 and AXUI IP support
 *		Michael Riepe	:	Automatic CSLIP recognition added
 *		Charles Hedrick :	CSLIP header length problem fix.
 *		Alan Cox	:	Corrected non-IP cases of the above.
 */
 
#include <asm/segment.h>
#include <asm/system.h>

#include <linux/config.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/socket.h>
#include <linux/sockios.h>
#include <linux/interrupt.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/stat.h>
#include <linux/in.h>
#include "inet.h"
#include "dev.h"
#ifdef CONFIG_AX25
#include "ax25.h"
#endif
#include "eth.h"
#include "ip.h"
#include "route.h"
#include "protocol.h"
#include "tcp.h"
#include "skbuff.h"
#include "sock.h"
#include "arp.h"
#include "slip.h"
#include "slhc.h"

#define	SLIP_VERSION	"0.7.5"

/* Define some IP layer stuff.  Not all systems have it. */
#ifdef SL_DUMP
#   define	IP_VERSION	4	/* version# of our IP software	*/
#   define	IPF_F_OFFSET	0x1fff	/* Offset field			*/
#   define	IPF_DF		0x4000	/* Don't fragment flag		*/
#   define	IPF_MF		0x2000	/* More Fragments flag		*/
#   define	IP_OF_COPIED	0x80	/* Copied-on-fragmentation flag	*/
#   define	IP_OF_CLASS	0x60	/* Option class			*/
#   define	IP_OF_NUMBER	0x1f	/* Option number		*/
#endif


static struct slip	sl_ctrl[SL_NRUNIT];
static struct tty_ldisc	sl_ldisc;
static int		already = 0;


/* Dump the contents of an IP datagram. */
static void
ip_dump(unsigned char *ptr, int len)
{
#ifdef SL_DUMP
  struct iphdr *ip;
  struct tcphdr *th;
  int dlen, doff;

  if (inet_debug != DBG_SLIP) return;

  ip = (struct iphdr *) ptr;
  th = (struct tcphdr *) (ptr + ip->ihl * 4);
  printk("\r%s -> %s seq %lx ack %lx len %d\n",
	 in_ntoa(ip->saddr), in_ntoa(ip->daddr), 
	 ntohl(th->seq), ntohl(th->ack_seq), ntohs(ip->tot_len));
  return;

  printk("\r*****\n");
  printk("%p %d\n", ptr, len);
  ip = (struct iphdr *) ptr;
  dlen = ntohs(ip->tot_len);
  doff = ((ntohs(ip->frag_off) & IPF_F_OFFSET) << 3);


  printk("SLIP: %s->", in_ntoa(ip->saddr));
  printk("%s\n", in_ntoa(ip->daddr));
  printk(" len %u ihl %u ver %u ttl %u prot %u",
	dlen, ip->ihl, ip->version, ip->ttl, ip->protocol);

  if (ip->tos != 0) printk(" tos %u", ip->tos);
  if (doff != 0 || (ntohs(ip->frag_off) & IPF_MF))
	printk(" id %u offs %u", ntohs(ip->id), doff);

  if (ntohs(ip->frag_off) & IPF_DF) printk(" DF");
  if (ntohs(ip->frag_off) & IPF_MF) printk(" MF");
  printk("\n*****\n");
#endif
}

#if 0
void clh_dump(unsigned char *cp, int len)
{
  if (len > 60)
    len = 60;
  printk("%d:", len);
  while (len > 0) {
    printk(" %x", *cp++);
    len--;
  }
  printk("\n\n");
}
#endif

/* Initialize a SLIP control block for use. */
static void
sl_initialize(struct slip *sl, struct device *dev)
{
  sl->inuse		= 0;
  sl->sending		= 0;
  sl->escape		= 0;
  sl->flags		= 0;
#ifdef SL_ADAPTIVE
  sl->mode		= SL_MODE_ADAPTIVE;	/* automatic CSLIP recognition */
#else
#ifdef SL_COMPRESSED
  sl->mode		= SL_MODE_CSLIP | SL_MODE_ADAPTIVE;	/* Default */
#else
  sl->mode		= SL_MODE_SLIP;		/* Default for non compressors */
#endif
#endif  

  sl->line		= dev->base_addr;
  sl->tty		= NULL;
  sl->dev		= dev;
  sl->slcomp		= NULL;

  /* Clear all pointers. */
  sl->rbuff		= NULL;
  sl->xbuff		= NULL;
  sl->cbuff		= NULL;

  sl->rhead		= NULL;
  sl->rend		= NULL;
  dev->rmem_end		= (unsigned long) NULL;
  dev->rmem_start	= (unsigned long) NULL;
  dev->mem_end		= (unsigned long) NULL;
  dev->mem_start	= (unsigned long) NULL;
}


/* Find a SLIP channel from its `tty' link. */
static struct slip *
sl_find(struct tty_struct *tty)
{
  struct slip *sl;
  int i;

  if (tty == NULL) return(NULL);
  for (i = 0; i < SL_NRUNIT; i++) {
	sl = &sl_ctrl[i];
	if (sl->tty == tty) return(sl);
  }
  return(NULL);
}


/* Find a free SLIP channel, and link in this `tty' line. */
static inline struct slip *
sl_alloc(void)
{
  unsigned long flags;
  struct slip *sl;
  int i;

  save_flags (flags);
  cli();
  for (i = 0; i < SL_NRUNIT; i++) {
	sl = &sl_ctrl[i];
	if (sl->inuse == 0) {
		sl->inuse = 1;
		sl->tty = NULL;
		restore_flags(flags);
		return(sl);
	}
  }
  restore_flags(flags);
  return(NULL);
}


/* Free a SLIP channel. */
static inline void
sl_free(struct slip *sl)
{
  unsigned long flags;

  if (sl->inuse) {
  	save_flags(flags);
  	cli();
	sl->inuse = 0;
	sl->tty = NULL;
	restore_flags(flags);
  }
}

/* MTU has been changed by the IP layer. Unfortunately we are not told about this, but
   we spot it ourselves and fix things up. We could be in an upcall from the tty
   driver, or in an ip packet queue. */
   
static void sl_changedmtu(struct slip *sl)
{
	struct device *dev=sl->dev;
	unsigned char *tb,*rb,*cb,*tf,*rf,*cf;
	int l;
	int omtu=sl->mtu;
	
	sl->mtu=dev->mtu;
	l=(dev->mtu *2);
/*
 * allow for arrival of larger UDP packets, even if we say not to
 * also fixes a bug in which SunOS sends 512-byte packets even with
 * an MSS of 128
 */
	if (l < (576 * 2))
	  l = 576 * 2;
	
	DPRINTF((DBG_SLIP,"SLIP: mtu changed!\n"));
	
	tb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
	rb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
	cb= (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
	
	if(tb==NULL || rb==NULL || cb==NULL)
	{
		printk("Unable to grow slip buffers. MTU change cancelled.\n");
		sl->mtu=omtu;
		dev->mtu=omtu;
		if(tb!=NULL)
			kfree(tb);
		if(rb!=NULL)
			kfree(rb);
		if(cb!=NULL)
			kfree(cb);
		return;
	}
	
	cli();
	
	tf=(unsigned char *)sl->dev->mem_start;
	sl->dev->mem_start=(unsigned long)tb;
	sl->dev->mem_end=(unsigned long) (sl->dev->mem_start + l);
	rf=(unsigned char *)sl->dev->rmem_start;
	sl->dev->rmem_start=(unsigned long)rb;
	sl->dev->rmem_end=(unsigned long) (sl->dev->rmem_start + l);
	
	sl->xbuff = (unsigned char *) sl->dev->mem_start;
	sl->rbuff = (unsigned char *) sl->dev->rmem_start;
	sl->rend  = (unsigned char *) sl->dev->rmem_end;
	sl->rhead = sl->rbuff;
	
	cf=sl->cbuff;
	sl->cbuff=cb;
	
	sl->escape=0;
	sl->sending=0;
	sl->rcount=0;

	sti();	
	
	if(rf!=NULL)
		kfree(rf);
	if(tf!=NULL)
		kfree(tf);
	if(cf!=NULL)
		kfree(cf);
}


/* Stuff one byte into a SLIP receiver buffer. */
static inline void
sl_enqueue(struct slip *sl, unsigned char c)
{
  unsigned long flags;

  save_flags(flags);
  cli();
  if (sl->rhead < sl->rend) {
	*sl->rhead = c;
	sl->rhead++;
	sl->rcount++;
  } else sl->roverrun++;
  restore_flags(flags);
}

/* Release 'i' bytes from a SLIP receiver buffer. */
static inline void
sl_dequeue(struct slip *sl, int i)
{
  unsigned long flags;

  save_flags(flags);
  cli();
  if (sl->rhead > sl->rbuff) {
	sl->rhead -= i;
	sl->rcount -= i;
  }
  restore_flags(flags);
}


/* Set the "sending" flag.  This must be atomic, hence the ASM. */
static inline void
sl_lock(struct slip *sl)
{
  unsigned long flags;

  save_flags(flags);
  cli();
  sl->sending = 1;
  sl->dev->tbusy = 1;
  restore_flags(flags);
}


/* Clear the "sending" flag.  This must be atomic, hence the ASM. */
static inline void
sl_unlock(struct slip *sl)
{
  unsigned long flags;

  save_flags(flags);
  cli();
  sl->sending = 0;
  sl->dev->tbusy = 0;
  restore_flags(flags);
}


/* Send one completely decapsulated IP datagram to the IP layer. */
static void
sl_bump(struct slip *sl)
{
  int done;
  unsigned char c;
  unsigned long flags;
  int count;

  count = sl->rcount;
  if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
    if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
#if 1
      /* ignore compressed packets when CSLIP is off */
      if (!(sl->mode & SL_MODE_CSLIP)) {
	printk("SLIP: compressed packet ignored\n");
	return;
      }
#endif
      /* make sure we've reserved enough space for uncompress to use */
      save_flags(flags);
      cli();
      if ((sl->rhead + 80) < sl->rend) {
	sl->rhead += 80;
	sl->rcount += 80;
	done = 1;
      } else {
	sl->roverrun++;
	done = 0;
      }
      restore_flags(flags);
      if (! done)  /* not enough space available */
	return;

      count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
      if (count <= 0) {
	sl->errors++;
	return;
      }
    } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
      if (!(sl->mode & SL_MODE_CSLIP)) {
	/* turn on header compression */
	sl->mode |= SL_MODE_CSLIP;
	printk("SLIP: header compression turned on\n");
      }
      sl->rbuff[0] &= 0x4f;
      if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
	sl->errors++;
	return;
      }
    }
  }

  DPRINTF((DBG_SLIP, "<< \"%s\" recv:\r\n", sl->dev->name));
  ip_dump(sl->rbuff, sl->rcount);

  /* Bump the datagram to the upper layers... */
  do {
	DPRINTF((DBG_SLIP, "SLIP: packet is %d at 0x%X\n",
					sl->rcount, sl->rbuff));
	/* clh_dump(sl->rbuff, count); */
	done = dev_rint(sl->rbuff, count, 0, sl->dev);
	if (done == 0 || done == 1) break;
  } while(1);

  sl->rpacket++;
}


/* TTY finished sending a datagram, so clean up. */
static void
sl_next(struct slip *sl)
{
  DPRINTF((DBG_SLIP, "SLIP: sl_next(0x%X) called!\n", sl));
  sl_unlock(sl);
  dev_tint(sl->dev);
}


/* Encapsulate one IP datagram and stuff into a TTY queue. */
static void
sl_encaps(struct slip *sl, unsigned char *icp, int len)
{
  unsigned char *bp, *p;
  int count;

  DPRINTF((DBG_SLIP, "SLIP: sl_encaps(0x%X, %d) called\n", icp, len));
  DPRINTF((DBG_SLIP, ">> \"%s\" sent:\r\n", sl->dev->name));
  
  ip_dump(icp, len);
  
  if(sl->mtu != sl->dev->mtu)	/* Someone has been ifconfigging */
  	sl_changedmtu(sl);
  
  if(len>sl->mtu)		/* Sigh, shouldn't occur BUT ... */
  {
  	len=sl->mtu;
  	printk("slip: truncating oversized transmit packet!\n");
  }

  p = icp;
  if(sl->mode & SL_MODE_CSLIP)
	  len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);

#ifdef OLD  
  /*
   * Send an initial END character to flush out any
   * data that may have accumulated in the receiver
   * due to line noise.
   */
  bp = sl->xbuff;
  *bp++ = END;
  count = 1;

  /*
   * For each byte in the packet, send the appropriate
   * character sequence, according to the SLIP protocol.
   */
  while(len-- > 0) {
	c = *p++;
	switch(c) {
		case END:
			*bp++ = ESC;
			*bp++ = ESC_END;
			count += 2;
                       	break;
		case ESC:
			*bp++ = ESC;
			*bp++ = ESC_ESC;
			count += 2;
                       	break;
		default:
			*bp++ = c;
			count++;
	}
  }
  *bp++ = END;  
  count++;
#else
  if(sl->mode & SL_MODE_SLIP6)
  	count=slip_esc6(p, (unsigned char *)sl->xbuff,len);
  else
  	count=slip_esc(p, (unsigned char *)sl->xbuff,len);
#endif  	  
  sl->spacket++;
  bp = sl->xbuff;

  /* Tell TTY to send it on its way. */
  DPRINTF((DBG_SLIP, "SLIP: kicking TTY for %d bytes at 0x%X\n", count, bp));
  if (tty_write_data(sl->tty, (char *) bp, count,
	     (void (*)(void *))sl_next, (void *) sl) == 0) {
	DPRINTF((DBG_SLIP, "SLIP: TTY already done with %d bytes!\n", count));
	sl_next(sl);
  }
}

/*static void sl_hex_dump(unsigned char *x,int l)
{
	int n=0;
	printk("sl_xmit: (%d bytes)\n",l);
	while(l)
	{
		printk("%2X ",(int)*x++);
		l--;
		n++;
		if(n%32==0)
			printk("\n");
	}
	if(n%32)
		printk("\n");
}*/

/* Encapsulate an IP datagram and kick it into a TTY queue. */
static int
sl_xmit(struct sk_buff *skb, struct device *dev)
{
  struct tty_struct *tty;
  struct slip *sl;
  int size;

  /* Find the correct SLIP channel to use. */
  sl = &sl_ctrl[dev->base_addr];
  tty = sl->tty;
  DPRINTF((DBG_SLIP, "SLIP: sl_xmit(\"%s\") skb=0x%X busy=%d\n",
				dev->name, skb, sl->sending));

  /*
   * If we are busy already- too bad.  We ought to be able
   * to queue things at this point, to allow for a little
   * frame buffer.  Oh well...
   */
  if (sl->sending) {
	DPRINTF((DBG_SLIP, "SLIP: sl_xmit: BUSY\r\n"));
	sl->sbusy++;
	return(1);
  }

  /* We were not, so we are now... :-) */
  if (skb != NULL) {
#ifdef CONFIG_AX25  
	if(sl->mode & SL_MODE_AX25)
	{
		if(!skb->arp && dev->rebuild_header(skb->data,dev))
		{
			skb->dev=dev;
			arp_queue(skb);
			return 0;
		}
		skb->arp=1;
	}
#endif  	
	sl_lock(sl);
	size = skb->len;
	if (!(sl->mode & SL_MODE_AX25)) {
		if (size < sizeof(struct iphdr)) {
			printk("Runt IP frame fed to slip!\n");
		} else {
			size = ((struct iphdr *)(skb->data))->tot_len;
			size = ntohs(size);
		}
	}
	/*	sl_hex_dump(skb->data,skb->len);*/
	sl_encaps(sl, skb->data, size);
	if (skb->free)
		kfree_skb(skb, FREE_WRITE);
  }
  return(0);
}

/* Return the frame type ID.  This is normally IP but maybe be AX.25. */
static unsigned short
sl_type_trans (struct sk_buff *skb, struct device *dev)
{
#ifdef CONFIG_AX25
	struct slip *sl=&sl_ctrl[dev->base_addr];
	if(sl->mode&SL_MODE_AX25)
		return(NET16(ETH_P_AX25));
#endif
  return(NET16(ETH_P_IP));
}


/* Fill in the MAC-level header. Not used by SLIP. */
static int
sl_header(unsigned char *buff, struct device *dev, unsigned short type,
	  unsigned long daddr, unsigned long saddr, unsigned len)
{
#ifdef CONFIG_AX25
  struct slip *sl=&sl_ctrl[dev->base_addr];
  if((sl->mode&SL_MODE_AX25) && type!=NET16(ETH_P_AX25))
  	return ax25_encapsulate_ip(buff,dev,type,daddr,saddr,len);
#endif  

  return(0);
}


/* Add an ARP-entry for this device's broadcast address. Not used. */
static void
sl_add_arp(unsigned long addr, struct sk_buff *skb, struct device *dev)
{
#ifdef CONFIG_AX25
	struct slip *sl=&sl_ctrl[dev->base_addr];
	
	if(sl->mode&SL_MODE_AX25)
		arp_add(addr,((char *) skb->data)+8,dev);
#endif		
}


/* Rebuild the MAC-level header.  Not used by SLIP. */
static int
sl_rebuild_header(void *buff, struct device *dev)
{
#ifdef CONFIG_AX25
  struct slip *sl=&sl_ctrl[dev->base_addr];
  
  if(sl->mode&SL_MODE_AX25)
  	return ax25_rebuild_header(buff,dev);
#endif  
  return(0);
}


/* Open the low-level part of the SLIP channel. Easy! */
static int
sl_open(struct device *dev)
{
  struct slip *sl;
  unsigned char *p;
  unsigned long l;

  sl = &sl_ctrl[dev->base_addr];
  if (sl->tty == NULL) {
	DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
	return(-ENXIO);
  }
  sl->dev = dev;

  /*
   * Allocate the SLIP frame buffers:
   *
   * mem_end	Top of frame buffers
   * mem_start	Start of frame buffers
   * rmem_end	Top of RECV frame buffer
   * rmem_start	Start of RECV frame buffer
   */
  l = (dev->mtu * 2);
/*
 * allow for arrival of larger UDP packets, even if we say not to
 * also fixes a bug in which SunOS sends 512-byte packets even with
 * an MSS of 128
 */
  if (l < (576 * 2))
    l = 576 * 2;

  p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
  if (p == NULL) {
	DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP XMIT buffer!\n"));
	return(-ENOMEM);
  }
  
  sl->mtu		= dev->mtu;
  sl->dev->mem_start	= (unsigned long) p;
  sl->dev->mem_end	= (unsigned long) (sl->dev->mem_start + l);

  p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
  if (p == NULL) {
	DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP RECV buffer!\n"));
	return(-ENOMEM);
  }
  sl->dev->rmem_start	= (unsigned long) p;
  sl->dev->rmem_end	= (unsigned long) (sl->dev->rmem_start + l);

  sl->xbuff		= (unsigned char *) sl->dev->mem_start;
  sl->rbuff		= (unsigned char *) sl->dev->rmem_start;
  sl->rend		= (unsigned char *) sl->dev->rmem_end;
  sl->rhead		= sl->rbuff;

  sl->escape		= 0;
  sl->sending		= 0;
  sl->rcount		= 0;

  p = (unsigned char *) kmalloc(l + 4, GFP_KERNEL);
  if (p == NULL) {
  	kfree((unsigned char *)sl->dev->mem_start);
	DPRINTF((DBG_SLIP, "SLIP: no memory for SLIP COMPRESS buffer!\n"));
	return(-ENOMEM);
  }
  sl->cbuff		= p;

  sl->slcomp = slhc_init(16, 16);
  if (sl->slcomp == NULL) {
  	kfree((unsigned char *)sl->dev->mem_start);
  	kfree((unsigned char *)sl->dev->rmem_start);
  	kfree(sl->cbuff);
	DPRINTF((DBG_SLIP, "SLIP: no memory for SLCOMP!\n"));
	return(-ENOMEM);
  }

  dev->flags|=IFF_UP;
  /* Needed because address '0' is special */
  if(dev->pa_addr==0)
  	dev->pa_addr=ntohl(0xC0000001);
  DPRINTF((DBG_SLIP, "SLIP: channel %d opened.\n", sl->line));
  return(0);
}


/* Close the low-level part of the SLIP channel. Easy! */
static int
sl_close(struct device *dev)
{
  struct slip *sl;

  sl = &sl_ctrl[dev->base_addr];
  if (sl->tty == NULL) {
	DPRINTF((DBG_SLIP, "SLIP: channel %d not connected!\n", sl->line));
	return(-EBUSY);
  }
  sl_free(sl);

  /* Free all SLIP frame buffers. */
  kfree(sl->rbuff);
  kfree(sl->xbuff);
  kfree(sl->cbuff);
  slhc_free(sl->slcomp);

  sl_initialize(sl, dev);

  DPRINTF((DBG_SLIP, "SLIP: channel %d closed.\n", sl->line));
  return(0);
}


/*
 * Handle the 'receiver data ready' interrupt.
 * This function is called by the 'tty_io' module in the kernel when
 * a block of SLIP data has been received, which can now be decapsulated
 * and sent on to some IP layer for further processing.
 */
static void
slip_recv(struct tty_struct *tty)
{
  unsigned char buff[128];
  unsigned char *p;
  struct slip *sl;
  int count, error=0;
  
  DPRINTF((DBG_SLIP, "SLIP: slip_recv(%d) called\n", tty->line));
  if ((sl = sl_find(tty)) == NULL) return;	/* not connected */

  if(sl->mtu!=sl->dev->mtu)	/* Argh! mtu change time! - costs us the packet part received at the change */
  	sl_changedmtu(sl);
  	
  /* Suck the bytes out of the TTY queues. */
  do {
	count = tty_read_raw_data(tty, buff, 128);
	if (count <= 0)
	{
		count= - count;
		if(count)
			error=1;
		break;
	}
	p = buff;
#ifdef OLD	
	while (count--) {
		c = *p++;
		if (sl->escape) {
			if (c == ESC_ESC)
				sl_enqueue(sl, ESC);
			else if (c == ESC_END)
				sl_enqueue(sl, END);
			else
				printk ("SLIP: received wrong character\n");
			sl->escape = 0;
		} else {
			if (c == ESC)
				sl->escape = 1;
			else if (c == END) {
				if (sl->rcount > 2) sl_bump(sl);
				sl_dequeue(sl, sl->rcount);
				sl->rcount = 0;
			} else	sl_enqueue(sl, c);
		}
	}
#else
	if(sl->mode & SL_MODE_SLIP6)
		slip_unesc6(sl,buff,count,error);
	else
		slip_unesc(sl,buff,count,error);
#endif		
  } while(1);
  
}


/*
 * Open the high-level part of the SLIP channel.  
 * This function is called by the TTY module when the
 * SLIP line discipline is called for.  Because we are
 * sure the tty line exists, we only have to link it to
 * a free SLIP channel...
 */
static int
slip_open(struct tty_struct *tty)
{
  struct slip *sl;

  /* First make sure we're not already connected. */
  if ((sl = sl_find(tty)) != NULL) {
	DPRINTF((DBG_SLIP, "SLIP: TTY %d already connected to %s !\n",
					tty->line, sl->dev->name));
	return(-EEXIST);
  }

  /* OK.  Find a free SLIP channel to use. */
  if ((sl = sl_alloc()) == NULL) {
	DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected: all channels in use!\n",
						tty->line));
	return(-ENFILE);
  }
  sl->tty = tty;
  tty_read_flush(tty);
  tty_write_flush(tty);

  /* Perform the low-level SLIP initialization. */
  (void) sl_open(sl->dev);
  DPRINTF((DBG_SLIP, "SLIP: TTY %d connected to %s.\n",
				tty->line, sl->dev->name));

  /* Done.  We have linked the TTY line to a channel. */
  return(sl->line);
}

 
static struct enet_statistics *
sl_get_stats(struct device *dev)
{
    static struct enet_statistics stats;
    struct slip *sl;
    struct slcompress *comp;

    /* Find the correct SLIP channel to use. */
    sl = &sl_ctrl[dev->base_addr];
    if (! sl)
      return NULL;

    memset(&stats, 0, sizeof(struct enet_statistics));

    stats.rx_packets = sl->rpacket;
    stats.rx_over_errors = sl->roverrun;
    stats.tx_packets = sl->spacket;
    stats.tx_dropped = sl->sbusy;
    stats.rx_errors = sl->errors;

    comp = sl->slcomp;
    if (comp) {
      stats.rx_fifo_errors = comp->sls_i_compressed;
      stats.rx_dropped = comp->sls_i_tossed;
      stats.tx_fifo_errors = comp->sls_o_compressed;
      stats.collisions = comp->sls_o_misses;
    }

    return (&stats);
}

/*
 * Close down a SLIP channel.
 * This means flushing out any pending queues, and then restoring the
 * TTY line discipline to what it was before it got hooked to SLIP
 * (which usually is TTY again).
 */
static void
slip_close(struct tty_struct *tty)
{
  struct slip *sl;

  /* First make sure we're connected. */
  if ((sl = sl_find(tty)) == NULL) {
	DPRINTF((DBG_SLIP, "SLIP: TTY %d not connected !\n", tty->line));
	return;
  }

  (void) dev_close(sl->dev);
  DPRINTF((DBG_SLIP, "SLIP: TTY %d disconnected from %s.\n",
					tty->line, sl->dev->name));
}

 
 /************************************************************************
  *			STANDARD SLIP ENCAPSULATION			*
  ************************************************************************
  *
  */
 
 int
 slip_esc(unsigned char *s, unsigned char *d, int len)
 {
     int count = 0;
 
     /*
      * Send an initial END character to flush out any
      * data that may have accumulated in the receiver
      * due to line noise.
      */
 
     d[count++] = END;
 
     /*
      * For each byte in the packet, send the appropriate
      * character sequence, according to the SLIP protocol.
      */
 
     while(len-- > 0) {
     	switch(*s) {
     	case END:
     	    d[count++] = ESC;
     	    d[count++] = ESC_END;
 	    break;
 	case ESC:
     	    d[count++] = ESC;
     	    d[count++] = ESC_ESC;
 	    break;
 	default:
 	    d[count++] = *s;
 	}
 	++s;
     }
     d[count++] = END;
     return(count);
 }
 
 void
 slip_unesc(struct slip *sl, unsigned char *s, int count, int error)
 {
     int i;
 
     for (i = 0; i < count; ++i, ++s) {
 	switch(*s) {
 	case ESC:
 	    sl->flags |= SLF_ESCAPE;
 	    break;
 	case ESC_ESC:
 	    if (sl->flags & SLF_ESCAPE)
 	    	sl_enqueue(sl, ESC);
 	    else
 	        sl_enqueue(sl, *s);
	    sl->flags &= ~SLF_ESCAPE;
 	    break;
	case ESC_END:
 	    if (sl->flags & SLF_ESCAPE)
	    	sl_enqueue(sl, END);
	    else
 	        sl_enqueue(sl, *s);
	    sl->flags &= ~SLF_ESCAPE;
	    break;
	case END:
 	    if (sl->rcount > 2) 
 	    	sl_bump(sl);
 	    sl_dequeue(sl, sl->rcount);
 	    sl->rcount = 0;
 	    sl->flags &= ~(SLF_ESCAPE | SLF_ERROR);
 	    break;
 	default:
 	    sl_enqueue(sl, *s);
 	    sl->flags &= ~SLF_ESCAPE;
 	}
     }
     if (error)
     	sl->flags |= SLF_ERROR;
 }
 
 /************************************************************************
  *			 6 BIT SLIP ENCAPSULATION			*
  ************************************************************************
  *
  */
 
 int
 slip_esc6(unsigned char *s, unsigned char *d, int len)
 {
     int count = 0;
     int i;
     unsigned short v = 0;
     short bits = 0;
 
     /*
      * Send an initial END character to flush out any
      * data that may have accumulated in the receiver
      * due to line noise.
      */
 
     d[count++] = 0x70;
 
     /*
      * Encode the packet into printable ascii characters
      */
 
     for (i = 0; i < len; ++i) {
     	v = (v << 8) | s[i];
     	bits += 8;
     	while (bits >= 6) {
     	    unsigned char c;
 
     	    bits -= 6;
     	    c = 0x30 + ((v >> bits) & 0x3F);
     	    d[count++] = c;
 	}
     }
     if (bits) {
     	unsigned char c;
 
     	c = 0x30 + ((v << (6 - bits)) & 0x3F);
     	d[count++] = c;
     }
     d[count++] = 0x70;
     return(count);
 }
 
 void
 slip_unesc6(struct slip *sl, unsigned char *s, int count, int error)
 {
     int i;
     unsigned char c;
 
     for (i = 0; i < count; ++i, ++s) {
     	if (*s == 0x70) {
 	    if (sl->rcount > 8) {	/* XXX must be 2 for compressed slip */
 #ifdef NOTDEF
 	        printk("rbuff %02x %02x %02x %02x\n",
 	            sl->rbuff[0],
 	            sl->rbuff[1],
 	            sl->rbuff[2],
 	            sl->rbuff[3]
 	        );
 #endif
 	    	sl_bump(sl);
 	    }
 	    sl_dequeue(sl, sl->rcount);
 	    sl->rcount = 0;
 	    sl->flags &= ~(SLF_ESCAPE | SLF_ERROR); /* SLF_ESCAPE not used */
 	    sl->xbits = 0;
 	} else if (*s >= 0x30 && *s < 0x70) {
 	    sl->xdata = (sl->xdata << 6) | ((*s - 0x30) & 0x3F);
 	    sl->xbits += 6;
 	    if (sl->xbits >= 8) {
 	    	sl->xbits -= 8;
 	    	c = (unsigned char)(sl->xdata >> sl->xbits);
 		sl_enqueue(sl, c);
 	    }
 
 	}
     }
     if (error)
     	sl->flags |= SLF_ERROR;
 }


#ifdef CONFIG_AX25

int sl_set_mac_address(struct device *dev, void *addr)
{
	int err=verify_area(VERIFY_READ,addr,7);
	if(err)
		return err;
	memcpy_fromfs(dev->dev_addr,addr,7);	/* addr is an AX.25 shifted ASCII mac address */
	return 0;
}
#endif


/* Perform I/O control on an active SLIP channel. */
static int
slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
{
  struct slip *sl;
  int err;

  /* First make sure we're connected. */
  if ((sl = sl_find(tty)) == NULL) {
	DPRINTF((DBG_SLIP, "SLIP: ioctl: TTY %d not connected !\n", tty->line));
	return(-EINVAL);
  }

  DPRINTF((DBG_SLIP, "SLIP: ioctl(%d, 0x%X, 0x%X)\n", tty->line, cmd, arg));
  switch(cmd) {
	case SIOCGIFNAME:
		err=verify_area(VERIFY_WRITE, arg, 16);
		if(err)
			return -err;
		memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
		return(0);
	case SIOCGIFENCAP:
		err=verify_area(VERIFY_WRITE,arg,sizeof(long));
		put_fs_long(sl->mode,(long *)arg);
		return(0);
	case SIOCSIFENCAP:
		err=verify_area(VERIFY_READ,arg,sizeof(long));
		sl->mode=get_fs_long((long *)arg);
#ifdef CONFIG_AX25		
		if(sl->mode & SL_MODE_AX25)
		{
			sl->dev->addr_len=7;	/* sizeof an AX.25 addr */
			sl->dev->hard_header_len=17;	/* We don't do digipeaters */
			sl->dev->type=3;		/* AF_AX25 not an AF_INET device */
		}
		else
		{
			sl->dev->addr_len=0;	/* No mac addr in slip mode */
			sl->dev->hard_header_len=0;
			sl->dev->type=0;
		}
#endif		
		return(0);
	case SIOCSIFHWADDR:
#ifdef CONFIG_AX25	
		return sl_set_mac_address(sl->dev,arg);
#endif
	default:
		return(-EINVAL);
  }
  return(-EINVAL);
}


/* Initialize the SLIP driver.  Called by DDI. */
int
slip_init(struct device *dev)
{
  struct slip *sl;
  int i;
#ifdef CONFIG_AX25  
  static char ax25_bcast[7]={'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
  static char ax25_test[7]={'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};
#endif

  sl = &sl_ctrl[dev->base_addr];

  if (already++ == 0) {
	printk("SLIP: version %s (%d channels)\n",
				SLIP_VERSION, SL_NRUNIT);
	printk("CSLIP: code copyright 1989 Regents of the University of California\n");
#ifdef CONFIG_AX25
	printk("AX25: KISS encapsulation enabled\n");
#endif	
	/* Fill in our LDISC request block. */
	sl_ldisc.flags	= 0;
	sl_ldisc.open	= slip_open;
	sl_ldisc.close	= slip_close;
	sl_ldisc.read	= NULL;
	sl_ldisc.write	= NULL;
	sl_ldisc.ioctl	= (int (*)(struct tty_struct *, struct file *,
				   unsigned int, unsigned long)) slip_ioctl;
	sl_ldisc.select = NULL;
	sl_ldisc.handler = slip_recv;
	if ((i = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)
		printk("ERROR: %d\n", i);
  }

  /* Set up the "SLIP Control Block". */
  sl_initialize(sl, dev);

  /* Clear all statistics. */
  sl->rcount		= 0;			/* SLIP receiver count	*/
  sl->rpacket		= 0;			/* #frames received	*/
  sl->roverrun		= 0;			/* "overrun" counter	*/
  sl->spacket		= 0;			/* #frames sent out	*/
  sl->sbusy		= 0;			/* "xmit busy" counter	*/
  sl->errors		= 0;			/* not used at present	*/

  /* Finish setting up the DEVICE info. */
  dev->mtu		= SL_MTU;
  dev->hard_start_xmit	= sl_xmit;
  dev->open		= sl_open;
  dev->stop		= sl_close;
  dev->hard_header	= sl_header;
  dev->add_arp		= sl_add_arp;
  dev->type_trans	= sl_type_trans;
  dev->get_stats	= sl_get_stats;
#ifdef HAVE_SET_MAC_ADDR
#ifdef CONFIG_AX25
  dev->set_mac_address  = sl_set_mac_address;
#endif
#endif
  dev->hard_header_len	= 0;
  dev->addr_len		= 0;
  dev->type		= 0;
#ifdef CONFIG_AX25  
  memcpy(dev->broadcast,ax25_bcast,7);		/* Only activated in AX.25 mode */
  memcpy(dev->dev_addr,ax25_test,7);		/*    ""      ""       ""    "" */
#endif  
  dev->queue_xmit	= dev_queue_xmit;
  dev->rebuild_header	= sl_rebuild_header;
  for (i = 0; i < DEV_NUMBUFFS; i++)
		dev->buffs[i] = NULL;

  /* New-style flags. */
  dev->flags		= 0;
  dev->family		= AF_INET;
  dev->pa_addr		= 0;
  dev->pa_brdaddr	= 0;
  dev->pa_mask		= 0;
  dev->pa_alen		= sizeof(unsigned long);

  return(0);
}
