/*
 *  This program is free software; you can distribute it and/or modify it
 *  under the terms of the GNU General Public License (Version 2) as
 *  published by the Free Software Foundation.
 *
 *  This program is distributed in the hope it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 *  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 *  for more details.
 *
 *  You should have received a copy of the GNU General Public License along
 *  with this program; if not, write to the Free Software Foundation, Inc.,
 *  59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
 *
 * Copyright (C) Hans Alblas PE1AYX <hans@esrac.ele.tue.nl>
 * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf@linux-mips.org>
 */

#include <linux/config.h>
#include <linux/module.h>
#include <asm/system.h>
#include <linux/bitops.h>
#include <asm/uaccess.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/inet.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/major.h>
#include <linux/init.h>
#include <linux/rtnetlink.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/jiffies.h>

#include <net/ax25.h>

#ifdef CONFIG_INET
#include <linux/ip.h>
#include <linux/tcp.h>
#endif

#define AX_MTU		236

/* SLIP/KISS protocol characters. */
#define END             0300		/* indicates end of frame	*/
#define ESC             0333		/* indicates byte stuffing	*/
#define ESC_END         0334		/* ESC ESC_END means END 'data'	*/
#define ESC_ESC         0335		/* ESC ESC_ESC means ESC 'data'	*/

struct mkiss {
	struct tty_struct	*tty;	/* ptr to TTY structure		*/
	struct net_device	*dev;	/* easy for intr handling	*/

	/* These are pointers to the malloc()ed frame buffers. */
	spinlock_t		buflock;/* lock for rbuf and xbuf */
	unsigned char		*rbuff;	/* receiver buffer		*/
	int			rcount;	/* received chars counter       */
	unsigned char		*xbuff;	/* transmitter buffer		*/
	unsigned char		*xhead;	/* pointer to next byte to XMIT */
	int			xleft;	/* bytes left in XMIT queue     */

	struct net_device_stats	stats;

	/* Detailed SLIP statistics. */
	int		mtu;		/* Our mtu (to spot changes!)   */
	int		buffsize;	/* Max buffers sizes            */

	unsigned long	flags;		/* Flag values/ mode etc	*/
					/* long req'd: used by set_bit --RR */
#define AXF_INUSE	0		/* Channel in use               */
#define AXF_ESCAPE	1               /* ESC received                 */
#define AXF_ERROR	2               /* Parity, etc. error           */
#define AXF_KEEPTEST	3		/* Keepalive test flag		*/
#define AXF_OUTWAIT	4		/* is outpacket was flag	*/

	int		mode;
        int		crcmode;	/* MW: for FlexNet, SMACK etc.  */
#define CRC_MODE_NONE   0
#define CRC_MODE_FLEX   1
#define CRC_MODE_SMACK  2

	atomic_t		refcnt;
	struct semaphore	dead_sem;
};

/*---------------------------------------------------------------------------*/

static const unsigned short crc_flex_table[] = {
	0x0f87, 0x1e0e, 0x2c95, 0x3d1c, 0x49a3, 0x582a, 0x6ab1, 0x7b38,
	0x83cf, 0x9246, 0xa0dd, 0xb154, 0xc5eb, 0xd462, 0xe6f9, 0xf770,
	0x1f06, 0x0e8f, 0x3c14, 0x2d9d, 0x5922, 0x48ab, 0x7a30, 0x6bb9,
	0x934e, 0x82c7, 0xb05c, 0xa1d5, 0xd56a, 0xc4e3, 0xf678, 0xe7f1,
	0x2e85, 0x3f0c, 0x0d97, 0x1c1e, 0x68a1, 0x7928, 0x4bb3, 0x5a3a,
	0xa2cd, 0xb344, 0x81df, 0x9056, 0xe4e9, 0xf560, 0xc7fb, 0xd672,
	0x3e04, 0x2f8d, 0x1d16, 0x0c9f, 0x7820, 0x69a9, 0x5b32, 0x4abb,
	0xb24c, 0xa3c5, 0x915e, 0x80d7, 0xf468, 0xe5e1, 0xd77a, 0xc6f3,
	0x4d83, 0x5c0a, 0x6e91, 0x7f18, 0x0ba7, 0x1a2e, 0x28b5, 0x393c,
	0xc1cb, 0xd042, 0xe2d9, 0xf350, 0x87ef, 0x9666, 0xa4fd, 0xb574,
	0x5d02, 0x4c8b, 0x7e10, 0x6f99, 0x1b26, 0x0aaf, 0x3834, 0x29bd,
	0xd14a, 0xc0c3, 0xf258, 0xe3d1, 0x976e, 0x86e7, 0xb47c, 0xa5f5,
	0x6c81, 0x7d08, 0x4f93, 0x5e1a, 0x2aa5, 0x3b2c, 0x09b7, 0x183e,
	0xe0c9, 0xf140, 0xc3db, 0xd252, 0xa6ed, 0xb764, 0x85ff, 0x9476,
	0x7c00, 0x6d89, 0x5f12, 0x4e9b, 0x3a24, 0x2bad, 0x1936, 0x08bf,
	0xf048, 0xe1c1, 0xd35a, 0xc2d3, 0xb66c, 0xa7e5, 0x957e, 0x84f7,
	0x8b8f, 0x9a06, 0xa89d, 0xb914, 0xcdab, 0xdc22, 0xeeb9, 0xff30,
	0x07c7, 0x164e, 0x24d5, 0x355c, 0x41e3, 0x506a, 0x62f1, 0x7378,
	0x9b0e, 0x8a87, 0xb81c, 0xa995, 0xdd2a, 0xcca3, 0xfe38, 0xefb1,
	0x1746, 0x06cf, 0x3454, 0x25dd, 0x5162, 0x40eb, 0x7270, 0x63f9,
	0xaa8d, 0xbb04, 0x899f, 0x9816, 0xeca9, 0xfd20, 0xcfbb, 0xde32,
	0x26c5, 0x374c, 0x05d7, 0x145e, 0x60e1, 0x7168, 0x43f3, 0x527a,
	0xba0c, 0xab85, 0x991e, 0x8897, 0xfc28, 0xeda1, 0xdf3a, 0xceb3,
	0x3644, 0x27cd, 0x1556, 0x04df, 0x7060, 0x61e9, 0x5372, 0x42fb,
	0xc98b, 0xd802, 0xea99, 0xfb10, 0x8faf, 0x9e26, 0xacbd, 0xbd34,
	0x45c3, 0x544a, 0x66d1, 0x7758, 0x03e7, 0x126e, 0x20f5, 0x317c,
	0xd90a, 0xc883, 0xfa18, 0xeb91, 0x9f2e, 0x8ea7, 0xbc3c, 0xadb5,
	0x5542, 0x44cb, 0x7650, 0x67d9, 0x1366, 0x02ef, 0x3074, 0x21fd,
	0xe889, 0xf900, 0xcb9b, 0xda12, 0xaead, 0xbf24, 0x8dbf, 0x9c36,
	0x64c1, 0x7548, 0x47d3, 0x565a, 0x22e5, 0x336c, 0x01f7, 0x107e,
	0xf808, 0xe981, 0xdb1a, 0xca93, 0xbe2c, 0xafa5, 0x9d3e, 0x8cb7,
	0x7440, 0x65c9, 0x5752, 0x46db, 0x3264, 0x23ed, 0x1176, 0x00ff
};

static unsigned short calc_crc_flex(unsigned char *cp, int size)
{
	unsigned short crc = 0xffff;

	while (size--)
		crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];

	return crc;
}

static int check_crc_flex(unsigned char *cp, int size)
{
	unsigned short crc = 0xffff;

	if (size < 3)
		return -1;

	while (size--)
		crc = (crc << 8) ^ crc_flex_table[((crc >> 8) ^ *cp++) & 0xff];

	if ((crc & 0xffff) != 0x7070)
		return -1;

	return 0;
}

/*
 * Standard encapsulation
 */

static int kiss_esc(unsigned char *s, unsigned char *d, int len)
{
	unsigned char *ptr = d;
	unsigned char c;

	/*
	 * Send an initial END character to flush out any data that may have
	 * accumulated in the receiver due to line noise.
	 */

	*ptr++ = END;

	while (len-- > 0) {
		switch (c = *s++) {
		case END:
			*ptr++ = ESC;
			*ptr++ = ESC_END;
			break;
		case ESC:
			*ptr++ = ESC;
			*ptr++ = ESC_ESC;
			break;
		default:
			*ptr++ = c;
			break;
		}
	}

	*ptr++ = END;

	return ptr - d;
}

/*
 * MW:
 * OK its ugly, but tell me a better solution without copying the
 * packet to a temporary buffer :-)
 */
static int kiss_esc_crc(unsigned char *s, unsigned char *d, unsigned short crc,
	int len)
{
	unsigned char *ptr = d;
	unsigned char c=0;

	*ptr++ = END;
	while (len > 0) {
		if (len > 2)
			c = *s++;
		else if (len > 1)
			c = crc >> 8;
		else if (len > 0)
			c = crc & 0xff;

		len--;

		switch (c) {
		case END:
			*ptr++ = ESC;
			*ptr++ = ESC_END;
			break;
		case ESC:
			*ptr++ = ESC;
			*ptr++ = ESC_ESC;
			break;
		default:
			*ptr++ = c;
			break;
		}
	}
	*ptr++ = END;

	return ptr - d;
}

/* Send one completely decapsulated AX.25 packet to the AX.25 layer. */
static void ax_bump(struct mkiss *ax)
{
	struct sk_buff *skb;
	int count;

	spin_lock_bh(&ax->buflock);
	if (ax->rbuff[0] > 0x0f) {
		if (ax->rbuff[0] & 0x20) {
		        ax->crcmode = CRC_MODE_FLEX;
			if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
			        ax->stats.rx_errors++;
				return;
			}
			ax->rcount -= 2;
                        /* dl9sau bugfix: the trailling two bytes flexnet crc
                         * will not be passed to the kernel. thus we have
                         * to correct the kissparm signature, because it
                         * indicates a crc but there's none
			 */
                        *ax->rbuff &= ~0x20;
		}
 	}
	spin_unlock_bh(&ax->buflock);

	count = ax->rcount;

	if ((skb = dev_alloc_skb(count)) == NULL) {
		printk(KERN_ERR "mkiss: %s: memory squeeze, dropping packet.\n",
		       ax->dev->name);
		ax->stats.rx_dropped++;
		return;
	}

	spin_lock_bh(&ax->buflock);
	memcpy(skb_put(skb,count), ax->rbuff, count);
	spin_unlock_bh(&ax->buflock);
	skb->protocol = ax25_type_trans(skb, ax->dev);
	netif_rx(skb);
	ax->dev->last_rx = jiffies;
	ax->stats.rx_packets++;
	ax->stats.rx_bytes += count;
}

static void kiss_unesc(struct mkiss *ax, unsigned char s)
{
	switch (s) {
	case END:
		/* drop keeptest bit = VSV */
		if (test_bit(AXF_KEEPTEST, &ax->flags))
			clear_bit(AXF_KEEPTEST, &ax->flags);

		if (!test_and_clear_bit(AXF_ERROR, &ax->flags) && (ax->rcount > 2))
			ax_bump(ax);

		clear_bit(AXF_ESCAPE, &ax->flags);
		ax->rcount = 0;
		return;

	case ESC:
		set_bit(AXF_ESCAPE, &ax->flags);
		return;
	case ESC_ESC:
		if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
			s = ESC;
		break;
	case ESC_END:
		if (test_and_clear_bit(AXF_ESCAPE, &ax->flags))
			s = END;
		break;
	}

	spin_lock_bh(&ax->buflock);
	if (!test_bit(AXF_ERROR, &ax->flags)) {
		if (ax->rcount < ax->buffsize) {
			ax->rbuff[ax->rcount++] = s;
			spin_unlock_bh(&ax->buflock);
			return;
		}

		ax->stats.rx_over_errors++;
		set_bit(AXF_ERROR, &ax->flags);
	}
	spin_unlock_bh(&ax->buflock);
}

static int ax_set_mac_address(struct net_device *dev, void *addr)
{
	struct sockaddr_ax25 *sa = addr;

	spin_lock_irq(&dev->xmit_lock);
	memcpy(dev->dev_addr, &sa->sax25_call, AX25_ADDR_LEN);
	spin_unlock_irq(&dev->xmit_lock);

	return 0;
}

/*---------------------------------------------------------------------------*/

static void ax_changedmtu(struct mkiss *ax)
{
	struct net_device *dev = ax->dev;
	unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
	int len;

	len = 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 (len < 576 * 2)
		len = 576 * 2;

	xbuff = kmalloc(len + 4, GFP_ATOMIC);
	rbuff = kmalloc(len + 4, GFP_ATOMIC);

	if (xbuff == NULL || rbuff == NULL)  {
		printk(KERN_ERR "mkiss: %s: unable to grow ax25 buffers, "
		       "MTU change cancelled.\n",
		       ax->dev->name);
		dev->mtu = ax->mtu;
		if (xbuff != NULL)
			kfree(xbuff);
		if (rbuff != NULL)
			kfree(rbuff);
		return;
	}

	spin_lock_bh(&ax->buflock);

	oxbuff    = ax->xbuff;
	ax->xbuff = xbuff;
	orbuff    = ax->rbuff;
	ax->rbuff = rbuff;

	if (ax->xleft) {
		if (ax->xleft <= len) {
			memcpy(ax->xbuff, ax->xhead, ax->xleft);
		} else  {
			ax->xleft = 0;
			ax->stats.tx_dropped++;
		}
	}

	ax->xhead = ax->xbuff;

	if (ax->rcount) {
		if (ax->rcount <= len) {
			memcpy(ax->rbuff, orbuff, ax->rcount);
		} else  {
			ax->rcount = 0;
			ax->stats.rx_over_errors++;
			set_bit(AXF_ERROR, &ax->flags);
		}
	}

	ax->mtu      = dev->mtu + 73;
	ax->buffsize = len;

	spin_unlock_bh(&ax->buflock);

	kfree(oxbuff);
	kfree(orbuff);
}

/* Encapsulate one AX.25 packet and stuff into a TTY queue. */
static void ax_encaps(struct net_device *dev, unsigned char *icp, int len)
{
	struct mkiss *ax = netdev_priv(dev);
	unsigned char *p;
	int actual, count;

	if (ax->mtu != ax->dev->mtu + 73)	/* Someone has been ifconfigging */
		ax_changedmtu(ax);

	if (len > ax->mtu) {		/* Sigh, shouldn't occur BUT ... */
		len = ax->mtu;
		printk(KERN_ERR "mkiss: %s: truncating oversized transmit packet!\n", ax->dev->name);
		ax->stats.tx_dropped++;
		netif_start_queue(dev);
		return;
	}

	p = icp;

	spin_lock_bh(&ax->buflock);
        switch (ax->crcmode) {
	         unsigned short crc;

	case CRC_MODE_FLEX:
	         *p |= 0x20;
	         crc = calc_crc_flex(p, len);
		 count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
		 break;

	default:
	         count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
		 break;
	}
	
	set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
	actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
	ax->stats.tx_packets++;
	ax->stats.tx_bytes += actual;

	ax->dev->trans_start = jiffies;
	ax->xleft = count - actual;
	ax->xhead = ax->xbuff + actual;

	spin_unlock_bh(&ax->buflock);
}

/* Encapsulate an AX.25 packet and kick it into a TTY queue. */
static int ax_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct mkiss *ax = netdev_priv(dev);

	if (!netif_running(dev))  {
		printk(KERN_ERR "mkiss: %s: xmit call when iface is down\n", dev->name);
		return 1;
	}

	if (netif_queue_stopped(dev)) {
		/*
		 * May be we must check transmitter timeout here ?
		 *      14 Oct 1994 Dmitry Gorodchanin.
		 */
		if (time_before(jiffies, dev->trans_start + 20 * HZ)) {
			/* 20 sec timeout not reached */
			return 1;
		}

		printk(KERN_ERR "mkiss: %s: transmit timed out, %s?\n", dev->name,
		       (ax->tty->driver->chars_in_buffer(ax->tty) || ax->xleft) ?
		       "bad line quality" : "driver error");

		ax->xleft = 0;
		clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
		netif_start_queue(dev);
	}

	/* We were not busy, so we are now... :-) */
	if (skb != NULL) {
		netif_stop_queue(dev);
		ax_encaps(dev, skb->data, skb->len);
		kfree_skb(skb);
	}

	return 0;
}

static int ax_open_dev(struct net_device *dev)
{
	struct mkiss *ax = netdev_priv(dev);

	if (ax->tty == NULL)
		return -ENODEV;

	return 0;
}

#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)

/* Return the frame type ID */
static int ax_header(struct sk_buff *skb, struct net_device *dev, unsigned short type,
	  void *daddr, void *saddr, unsigned len)
{
#ifdef CONFIG_INET
	if (type != htons(ETH_P_AX25))
		return ax25_hard_header(skb, dev, type, daddr, saddr, len);
#endif
	return 0;
}


static int ax_rebuild_header(struct sk_buff *skb)
{
#ifdef CONFIG_INET
	return ax25_rebuild_header(skb);
#else
	return 0;
#endif
}

#endif	/* CONFIG_{AX25,AX25_MODULE} */

/* Open the low-level part of the AX25 channel. Easy! */
static int ax_open(struct net_device *dev)
{
	struct mkiss *ax = netdev_priv(dev);
	unsigned long len;

	if (ax->tty == NULL)
		return -ENODEV;

	/*
	 * Allocate the frame buffers:
	 *
	 * rbuff	Receive buffer.
	 * xbuff	Transmit buffer.
	 */
	len = 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 (len < 576 * 2)
		len = 576 * 2;

	if ((ax->rbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
		goto norbuff;

	if ((ax->xbuff = kmalloc(len + 4, GFP_KERNEL)) == NULL)
		goto noxbuff;

	ax->mtu	     = dev->mtu + 73;
	ax->buffsize = len;
	ax->rcount   = 0;
	ax->xleft    = 0;

	ax->flags   &= (1 << AXF_INUSE);      /* Clear ESCAPE & ERROR flags */

	spin_lock_init(&ax->buflock);

	return 0;

noxbuff:
	kfree(ax->rbuff);

norbuff:
	return -ENOMEM;
}


/* Close the low-level part of the AX25 channel. Easy! */
static int ax_close(struct net_device *dev)
{
	struct mkiss *ax = netdev_priv(dev);

	if (ax->tty)
		clear_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);

	netif_stop_queue(dev);

	return 0;
}

static struct net_device_stats *ax_get_stats(struct net_device *dev)
{
	struct mkiss *ax = netdev_priv(dev);

	return &ax->stats;
}

static void ax_setup(struct net_device *dev)
{
	static char ax25_bcast[AX25_ADDR_LEN] =
		{'Q'<<1,'S'<<1,'T'<<1,' '<<1,' '<<1,' '<<1,'0'<<1};
	static char ax25_test[AX25_ADDR_LEN] =
		{'L'<<1,'I'<<1,'N'<<1,'U'<<1,'X'<<1,' '<<1,'1'<<1};

	/* Finish setting up the DEVICE info. */
	dev->mtu             = AX_MTU;
	dev->hard_start_xmit = ax_xmit;
	dev->open            = ax_open_dev;
	dev->stop            = ax_close;
	dev->get_stats	     = ax_get_stats;
	dev->set_mac_address = ax_set_mac_address;
	dev->hard_header_len = 0;
	dev->addr_len        = 0;
	dev->type            = ARPHRD_AX25;
	dev->tx_queue_len    = 10;
	dev->hard_header     = ax_header;
	dev->rebuild_header  = ax_rebuild_header;

	memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
	memcpy(dev->dev_addr,  ax25_test,  AX25_ADDR_LEN);

	dev->flags      = IFF_BROADCAST | IFF_MULTICAST;
}

/*
 * We have a potential race on dereferencing tty->disc_data, because the tty
 * layer provides no locking at all - thus one cpu could be running
 * sixpack_receive_buf while another calls sixpack_close, which zeroes
 * tty->disc_data and frees the memory that sixpack_receive_buf is using.  The
 * best way to fix this is to use a rwlock in the tty struct, but for now we
 * use a single global rwlock for all ttys in ppp line discipline.
 */
static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;

static struct mkiss *mkiss_get(struct tty_struct *tty)
{
	struct mkiss *ax;

	read_lock(&disc_data_lock);
	ax = tty->disc_data;
	if (ax)
		atomic_inc(&ax->refcnt);
	read_unlock(&disc_data_lock);

	return ax;
}

static void mkiss_put(struct mkiss *ax)
{
	if (atomic_dec_and_test(&ax->refcnt))
		up(&ax->dead_sem);
}

static int mkiss_open(struct tty_struct *tty)
{
	struct net_device *dev;
	struct mkiss *ax;
	int err;

	if (!capable(CAP_NET_ADMIN))
		return -EPERM;

	dev = alloc_netdev(sizeof(struct mkiss), "ax%d", ax_setup);
	if (!dev) {
		err = -ENOMEM;
		goto out;
	}

	ax = netdev_priv(dev);
	ax->dev = dev;

	spin_lock_init(&ax->buflock);
	atomic_set(&ax->refcnt, 1);
	init_MUTEX_LOCKED(&ax->dead_sem);

	ax->tty = tty;
	tty->disc_data = ax;

	if (tty->driver->flush_buffer)
		tty->driver->flush_buffer(tty);

	/* Restore default settings */
	dev->type = ARPHRD_AX25;

	/* Perform the low-level AX25 initialization. */
	if ((err = ax_open(ax->dev))) {
		goto out_free_netdev;
	}

	if (register_netdev(dev))
		goto out_free_buffers;

	netif_start_queue(dev);

	/* Done.  We have linked the TTY line to a channel. */
	return 0;

out_free_buffers:
	kfree(ax->rbuff);
	kfree(ax->xbuff);

out_free_netdev:
	free_netdev(dev);

out:
	return err;
}

static void mkiss_close(struct tty_struct *tty)
{
	struct mkiss *ax;

	write_lock(&disc_data_lock);
	ax = tty->disc_data;
	tty->disc_data = NULL;
	write_unlock(&disc_data_lock);

	if (ax == 0)
		return;

	/*
	 * We have now ensured that nobody can start using ap from now on, but
	 * we have to wait for all existing users to finish.
	 */
	if (!atomic_dec_and_test(&ax->refcnt))
		down(&ax->dead_sem);

	unregister_netdev(ax->dev);

	/* Free all AX25 frame buffers. */
	kfree(ax->rbuff);
	kfree(ax->xbuff);

	ax->tty = NULL;
}

/* Perform I/O control on an active ax25 channel. */
static int mkiss_ioctl(struct tty_struct *tty, struct file *file,
	unsigned int cmd, unsigned long arg)
{
	struct mkiss *ax = mkiss_get(tty);
	struct net_device *dev = ax->dev;
	unsigned int tmp, err;

	/* First make sure we're connected. */
	if (ax == NULL)
		return -ENXIO;

	switch (cmd) {
 	case SIOCGIFNAME:
		err = copy_to_user((void __user *) arg, ax->dev->name,
		                   strlen(ax->dev->name) + 1) ? -EFAULT : 0;
		break;

	case SIOCGIFENCAP:
		err = put_user(4, (int __user *) arg);
		break;

	case SIOCSIFENCAP:
		if (get_user(tmp, (int __user *) arg)) {
			err = -EFAULT;
			break;
		}

		ax->mode = tmp;
		dev->addr_len        = AX25_ADDR_LEN;
		dev->hard_header_len = AX25_KISS_HEADER_LEN +
		                       AX25_MAX_HEADER_LEN + 3;
		dev->type            = ARPHRD_AX25;

		err = 0;
		break;

	case SIOCSIFHWADDR: {
		char addr[AX25_ADDR_LEN];
printk(KERN_INFO "In SIOCSIFHWADDR");

		if (copy_from_user(&addr,
		                   (void __user *) arg, AX25_ADDR_LEN)) {
			err = -EFAULT;
			break;
		}

		spin_lock_irq(&dev->xmit_lock);
		memcpy(dev->dev_addr, addr, AX25_ADDR_LEN);
		spin_unlock_irq(&dev->xmit_lock);

		err = 0;
		break;
	}
	default:
		err = -ENOIOCTLCMD;
	}

	mkiss_put(ax);

	return err;
}

/*
 * Handle the 'receiver data ready' interrupt.
 * This function is called by the 'tty_io' module in the kernel when
 * a block of data has been received, which can now be decapsulated
 * and sent on to the AX.25 layer for further processing.
 */
static void mkiss_receive_buf(struct tty_struct *tty, const unsigned char *cp,
	char *fp, int count)
{
	struct mkiss *ax = mkiss_get(tty);

	if (!ax)
		return;

	/*
	 * Argh! mtu change time! - costs us the packet part received
	 * at the change
	 */
	if (ax->mtu != ax->dev->mtu + 73)
		ax_changedmtu(ax);

	/* Read the characters out of the buffer */
	while (count--) {
		if (fp != NULL && *fp++) {
			if (!test_and_set_bit(AXF_ERROR, &ax->flags))
				ax->stats.rx_errors++;
			cp++;
			continue;
		}

		kiss_unesc(ax, *cp++);
	}

	mkiss_put(ax);
	if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
	    && tty->driver->unthrottle)
		tty->driver->unthrottle(tty);
}

static int mkiss_receive_room(struct tty_struct *tty)
{
	return 65536;  /* We can handle an infinite amount of data. :-) */
}

/*
 * Called by the driver when there's room for more data.  If we have
 * more packets to send, we send them here.
 */
static void mkiss_write_wakeup(struct tty_struct *tty)
{
	struct mkiss *ax = mkiss_get(tty);
	int actual;

	if (!ax)
		return;

	if (ax->xleft <= 0)  {
		/* Now serial buffer is almost free & we can start
		 * transmission of another packet
		 */
		clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);

		netif_wake_queue(ax->dev);
		goto out;
	}

	actual = tty->driver->write(tty, ax->xhead, ax->xleft);
	ax->xleft -= actual;
	ax->xhead += actual;

out:
	mkiss_put(ax);
}

static struct tty_ldisc ax_ldisc = {
	.magic		= TTY_LDISC_MAGIC,
	.name		= "mkiss",
	.open		= mkiss_open,
	.close		= mkiss_close,
	.ioctl		= mkiss_ioctl,
	.receive_buf	= mkiss_receive_buf,
	.receive_room	= mkiss_receive_room,
	.write_wakeup	= mkiss_write_wakeup
};

static char banner[] __initdata = KERN_INFO \
	"mkiss: AX.25 Multikiss, Hans Albas PE1AYX\n";
static char msg_regfail[] __initdata = KERN_ERR \
	"mkiss: can't register line discipline (err = %d)\n";

static int __init mkiss_init_driver(void)
{
	int status;

	printk(banner);

	if ((status = tty_register_ldisc(N_AX25, &ax_ldisc)) != 0)
		printk(msg_regfail);

	return status;
}

static const char msg_unregfail[] __exitdata = KERN_ERR \
	"mkiss: can't unregister line discipline (err = %d)\n";

static void __exit mkiss_exit_driver(void)
{
	int ret;

	if ((ret = tty_unregister_ldisc(N_AX25)))
		printk(msg_unregfail, ret);
}

MODULE_AUTHOR("Ralf Baechle DL5RB <ralf@linux-mips.org>");
MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
MODULE_LICENSE("GPL");
MODULE_ALIAS_LDISC(N_AX25);

module_init(mkiss_init_driver);
module_exit(mkiss_exit_driver);
