/*
 * SDLA		An implementation of a driver for the Sangoma S502/S508 series
 *		multi-protocol PC interface card.  Initial offering is with 
 *		the DLCI driver, providing Frame Relay support for linux.
 *
 *		Global definitions for the Frame relay interface.
 *
 * Version:	@(#)sdla.c   0.30	12 Sep 1996
 *
 * Credits:	Sangoma Technologies, for the use of 2 cards for an extended
 *			period of time.
 *		David Mandelstam <dm@sangoma.com> for getting me started on 
 *			this project, and incentive to complete it.
 *		Gene Kozen <74604.152@compuserve.com> for providing me with
 *			important information about the cards.
 *
 * Author:	Mike McLagan <mike.mclagan@linux.org>
 *
 * Changes:
 *		0.15	Mike McLagan	Improved error handling, packet dropping
 *		0.20	Mike McLagan	New transmit/receive flags for config
 *					If in FR mode, don't accept packets from
 *					non DLCI devices.
 *		0.25	Mike McLagan	Fixed problem with rejecting packets
 *					from non DLCI devices.
 *		0.30	Mike McLagan	Fixed kernel panic when used with modified
 *					ifconfig
 *
 *		This program is free software; you can redistribute it and/or
 *		modify it under the terms of the GNU General Public License
 *		as published by the Free Software Foundation; either version
 *		2 of the License, or (at your option) any later version.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/timer.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/if_frad.h>
#include <linux/sdla.h>
#include <linux/bitops.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>

static const char* version = "SDLA driver v0.30, 12 Sep 1996, mike.mclagan@linux.org";

static unsigned int valid_port[] = { 0x250, 0x270, 0x280, 0x300, 0x350, 0x360, 0x380, 0x390};

static unsigned int valid_mem[] = {
				    0xA0000, 0xA2000, 0xA4000, 0xA6000, 0xA8000, 0xAA000, 0xAC000, 0xAE000, 
                                    0xB0000, 0xB2000, 0xB4000, 0xB6000, 0xB8000, 0xBA000, 0xBC000, 0xBE000,
                                    0xC0000, 0xC2000, 0xC4000, 0xC6000, 0xC8000, 0xCA000, 0xCC000, 0xCE000,
                                    0xD0000, 0xD2000, 0xD4000, 0xD6000, 0xD8000, 0xDA000, 0xDC000, 0xDE000,
                                    0xE0000, 0xE2000, 0xE4000, 0xE6000, 0xE8000, 0xEA000, 0xEC000, 0xEE000}; 

static DEFINE_SPINLOCK(sdla_lock);

/*********************************************************
 *
 * these are the core routines that access the card itself 
 *
 *********************************************************/

#define SDLA_WINDOW(dev,addr) outb((((addr) >> 13) & 0x1F), (dev)->base_addr + SDLA_REG_Z80_WINDOW)

static void __sdla_read(struct net_device *dev, int addr, void *buf, short len)
{
	char          *temp;
	const void    *base;
	int           offset, bytes;

	temp = buf;
	while(len)
	{	
		offset = addr & SDLA_ADDR_MASK;
		bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
		base = (const void *) (dev->mem_start + offset);

		SDLA_WINDOW(dev, addr);
		memcpy(temp, base, bytes);

		addr += bytes;
		temp += bytes;
		len  -= bytes;
	}  
}

static void sdla_read(struct net_device *dev, int addr, void *buf, short len)
{
	unsigned long flags;
	spin_lock_irqsave(&sdla_lock, flags);
	__sdla_read(dev, addr, buf, len);
	spin_unlock_irqrestore(&sdla_lock, flags);
}

static void __sdla_write(struct net_device *dev, int addr, 
			 const void *buf, short len)
{
	const char    *temp;
	void 	      *base;
	int           offset, bytes;

	temp = buf;
	while(len)
	{
		offset = addr & SDLA_ADDR_MASK;
		bytes = offset + len > SDLA_WINDOW_SIZE ? SDLA_WINDOW_SIZE - offset : len;
		base = (void *) (dev->mem_start + offset);

		SDLA_WINDOW(dev, addr);
		memcpy(base, temp, bytes);

		addr += bytes;
		temp += bytes;
		len  -= bytes;
	}
}

static void sdla_write(struct net_device *dev, int addr, 
		       const void *buf, short len)
{
	unsigned long flags;

	spin_lock_irqsave(&sdla_lock, flags);
	__sdla_write(dev, addr, buf, len);
	spin_unlock_irqrestore(&sdla_lock, flags);
}


static void sdla_clear(struct net_device *dev)
{
	unsigned long flags;
	char          *base;
	int           len, addr, bytes;

	len = 65536;	
	addr = 0;
	bytes = SDLA_WINDOW_SIZE;
	base = (void *) dev->mem_start;

	spin_lock_irqsave(&sdla_lock, flags);
	while(len)
	{
		SDLA_WINDOW(dev, addr);
		memset(base, 0, bytes);

		addr += bytes;
		len  -= bytes;
	}
	spin_unlock_irqrestore(&sdla_lock, flags);

}

static char sdla_byte(struct net_device *dev, int addr)
{
	unsigned long flags;
	char          byte, *temp;

	temp = (void *) (dev->mem_start + (addr & SDLA_ADDR_MASK));

	spin_lock_irqsave(&sdla_lock, flags);
	SDLA_WINDOW(dev, addr);
	byte = *temp;
	spin_unlock_irqrestore(&sdla_lock, flags);

	return(byte);
}

static void sdla_stop(struct net_device *dev)
{
	struct frad_local *flp;

	flp = netdev_priv(dev);
	switch(flp->type)
	{
		case SDLA_S502A:
			outb(SDLA_S502A_HALT, dev->base_addr + SDLA_REG_CONTROL);
			flp->state = SDLA_HALT;
			break;
		case SDLA_S502E:
			outb(SDLA_HALT, dev->base_addr + SDLA_REG_Z80_CONTROL);
			outb(SDLA_S502E_ENABLE, dev->base_addr + SDLA_REG_CONTROL);
			flp->state = SDLA_S502E_ENABLE;
			break;
		case SDLA_S507:
			flp->state &= ~SDLA_CPUEN;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			break;
		case SDLA_S508:
			flp->state &= ~SDLA_CPUEN;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			break;
	}
}

static void sdla_start(struct net_device *dev)
{
	struct frad_local *flp;

	flp = netdev_priv(dev);
	switch(flp->type)
	{
		case SDLA_S502A:
			outb(SDLA_S502A_NMI, dev->base_addr + SDLA_REG_CONTROL);
			outb(SDLA_S502A_START, dev->base_addr + SDLA_REG_CONTROL);
			flp->state = SDLA_S502A_START;
			break;
		case SDLA_S502E:
			outb(SDLA_S502E_CPUEN, dev->base_addr + SDLA_REG_Z80_CONTROL);
			outb(0x00, dev->base_addr + SDLA_REG_CONTROL);
			flp->state = 0;
			break;
		case SDLA_S507:
			flp->state |= SDLA_CPUEN;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			break;
		case SDLA_S508:
			flp->state |= SDLA_CPUEN;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			break;
	}
}

/****************************************************
 *
 * this is used for the S502A/E cards to determine
 * the speed of the onboard CPU.  Calibration is
 * necessary for the Frame Relay code uploaded 
 * later.  Incorrect results cause timing problems
 * with link checks & status messages
 *
 ***************************************************/

static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
{
	unsigned long start, done, now;
	char          resp, *temp;

	start = now = jiffies;
	done = jiffies + jiffs;

	temp = (void *)dev->mem_start;
	temp += z80_addr & SDLA_ADDR_MASK;
	
	resp = ~resp1;
	while (time_before(jiffies, done) && (resp != resp1) && (!resp2 || (resp != resp2)))
	{
		if (jiffies != now)
		{
			SDLA_WINDOW(dev, z80_addr);
			now = jiffies;
			resp = *temp;
		}
	}
	return(time_before(jiffies, done) ? jiffies - start : -1);
}

/* constants for Z80 CPU speed */
#define Z80_READY 		'1'	/* Z80 is ready to begin */
#define LOADER_READY 		'2'	/* driver is ready to begin */
#define Z80_SCC_OK 		'3'	/* SCC is on board */
#define Z80_SCC_BAD	 	'4'	/* SCC was not found */

static int sdla_cpuspeed(struct net_device *dev, struct ifreq *ifr)
{
	int  jiffs;
	char data;

	sdla_start(dev);
	if (sdla_z80_poll(dev, 0, 3*HZ, Z80_READY, 0) < 0)
		return(-EIO);

	data = LOADER_READY;
	sdla_write(dev, 0, &data, 1);

	if ((jiffs = sdla_z80_poll(dev, 0, 8*HZ, Z80_SCC_OK, Z80_SCC_BAD)) < 0)
		return(-EIO);

	sdla_stop(dev);
	sdla_read(dev, 0, &data, 1);

	if (data == Z80_SCC_BAD)
	{
		printk("%s: SCC bad\n", dev->name);
		return(-EIO);
	}

	if (data != Z80_SCC_OK)
		return(-EINVAL);

	if (jiffs < 165)
		ifr->ifr_mtu = SDLA_CPU_16M;
	else if (jiffs < 220)
		ifr->ifr_mtu = SDLA_CPU_10M;
	else if (jiffs < 258)
		ifr->ifr_mtu = SDLA_CPU_8M;
	else if (jiffs < 357)
		ifr->ifr_mtu = SDLA_CPU_7M;
	else if (jiffs < 467)
		ifr->ifr_mtu = SDLA_CPU_5M;
	else
		ifr->ifr_mtu = SDLA_CPU_3M;
 
	return(0);
}

/************************************************
 *
 *  Direct interaction with the Frame Relay code 
 *  starts here.
 *
 ************************************************/

struct _dlci_stat 
{
	short dlci;
	char  flags;
} __attribute__((packed));

struct _frad_stat 
{
	char    flags;
	struct _dlci_stat dlcis[SDLA_MAX_DLCI];
};

static void sdla_errors(struct net_device *dev, int cmd, int dlci, int ret, int len, void *data) 
{
	struct _dlci_stat *pstatus;
	short             *pdlci;
	int               i;
	char              *state, line[30];

	switch (ret)
	{
		case SDLA_RET_MODEM:
			state = data;
			if (*state & SDLA_MODEM_DCD_LOW)
				printk(KERN_INFO "%s: Modem DCD unexpectedly low!\n", dev->name);
			if (*state & SDLA_MODEM_CTS_LOW)
				printk(KERN_INFO "%s: Modem CTS unexpectedly low!\n", dev->name);
			/* I should probably do something about this! */
			break;

		case SDLA_RET_CHANNEL_OFF:
			printk(KERN_INFO "%s: Channel became inoperative!\n", dev->name);
			/* same here */
			break;

		case SDLA_RET_CHANNEL_ON:
			printk(KERN_INFO "%s: Channel became operative!\n", dev->name);
			/* same here */
			break;

		case SDLA_RET_DLCI_STATUS:
			printk(KERN_INFO "%s: Status change reported by Access Node.\n", dev->name);
			len /= sizeof(struct _dlci_stat);
			for(pstatus = data, i=0;i < len;i++,pstatus++)
			{
				if (pstatus->flags & SDLA_DLCI_NEW)
					state = "new";
				else if (pstatus->flags & SDLA_DLCI_DELETED)
					state = "deleted";
				else if (pstatus->flags & SDLA_DLCI_ACTIVE)
					state = "active";
				else
				{
					sprintf(line, "unknown status: %02X", pstatus->flags);
					state = line;
				}
				printk(KERN_INFO "%s: DLCI %i: %s.\n", dev->name, pstatus->dlci, state);
				/* same here */
			}
			break;

		case SDLA_RET_DLCI_UNKNOWN:
			printk(KERN_INFO "%s: Received unknown DLCIs:", dev->name);
			len /= sizeof(short);
			for(pdlci = data,i=0;i < len;i++,pdlci++)
				printk(" %i", *pdlci);
			printk("\n");
			break;

		case SDLA_RET_TIMEOUT:
			printk(KERN_ERR "%s: Command timed out!\n", dev->name);
			break;

		case SDLA_RET_BUF_OVERSIZE:
			printk(KERN_INFO "%s: Bc/CIR overflow, acceptable size is %i\n", dev->name, len);
			break;

		case SDLA_RET_BUF_TOO_BIG:
			printk(KERN_INFO "%s: Buffer size over specified max of %i\n", dev->name, len);
			break;

		case SDLA_RET_CHANNEL_INACTIVE:
		case SDLA_RET_DLCI_INACTIVE:
		case SDLA_RET_CIR_OVERFLOW:
		case SDLA_RET_NO_BUFS:
			if (cmd == SDLA_INFORMATION_WRITE)
				break;

		default: 
			printk(KERN_DEBUG "%s: Cmd 0x%2.2X generated return code 0x%2.2X\n", dev->name, cmd, ret);
			/* Further processing could be done here */
			break;
	}
}

static int sdla_cmd(struct net_device *dev, int cmd, short dlci, short flags, 
                        void *inbuf, short inlen, void *outbuf, short *outlen)
{
	static struct _frad_stat status;
	struct frad_local        *flp;
	struct sdla_cmd          *cmd_buf;
	unsigned long            pflags;
	unsigned long		 jiffs;
	int                      ret, waiting, len;
	long                     window;

	flp = netdev_priv(dev);
	window = flp->type == SDLA_S508 ? SDLA_508_CMD_BUF : SDLA_502_CMD_BUF;
	cmd_buf = (struct sdla_cmd *)(dev->mem_start + (window & SDLA_ADDR_MASK));
	ret = 0;
	len = 0;
	jiffs = jiffies + HZ;  /* 1 second is plenty */

	spin_lock_irqsave(&sdla_lock, pflags);
	SDLA_WINDOW(dev, window);
	cmd_buf->cmd = cmd;
	cmd_buf->dlci = dlci;
	cmd_buf->flags = flags;

	if (inbuf)
		memcpy(cmd_buf->data, inbuf, inlen);

	cmd_buf->length = inlen;

	cmd_buf->opp_flag = 1;
	spin_unlock_irqrestore(&sdla_lock, pflags);

	waiting = 1;
	len = 0;
	while (waiting && time_before_eq(jiffies, jiffs))
	{
		if (waiting++ % 3) 
		{
			spin_lock_irqsave(&sdla_lock, pflags);
			SDLA_WINDOW(dev, window);
			waiting = ((volatile int)(cmd_buf->opp_flag));
			spin_unlock_irqrestore(&sdla_lock, pflags);
		}
	}
	
	if (!waiting)
	{

		spin_lock_irqsave(&sdla_lock, pflags);
		SDLA_WINDOW(dev, window);
		ret = cmd_buf->retval;
		len = cmd_buf->length;
		if (outbuf && outlen)
		{
			*outlen = *outlen >= len ? len : *outlen;

			if (*outlen)
				memcpy(outbuf, cmd_buf->data, *outlen);
		}

		/* This is a local copy that's used for error handling */
		if (ret)
			memcpy(&status, cmd_buf->data, len > sizeof(status) ? sizeof(status) : len);

		spin_unlock_irqrestore(&sdla_lock, pflags);
	}
	else
		ret = SDLA_RET_TIMEOUT;

	if (ret != SDLA_RET_OK)
	   	sdla_errors(dev, cmd, dlci, ret, len, &status);

	return(ret);
}

/***********************************************
 *
 * these functions are called by the DLCI driver 
 *
 ***********************************************/

static int sdla_reconfig(struct net_device *dev);

static int sdla_activate(struct net_device *slave, struct net_device *master)
{
	struct frad_local *flp;
	int i;

	flp = netdev_priv(slave);

	for(i=0;i<CONFIG_DLCI_MAX;i++)
		if (flp->master[i] == master)
			break;

	if (i == CONFIG_DLCI_MAX)
		return(-ENODEV);

	flp->dlci[i] = abs(flp->dlci[i]);

	if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE))
		sdla_cmd(slave, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);

	return(0);
}

static int sdla_deactivate(struct net_device *slave, struct net_device *master)
{
	struct frad_local *flp;
	int               i;

	flp = netdev_priv(slave);

	for(i=0;i<CONFIG_DLCI_MAX;i++)
		if (flp->master[i] == master)
			break;

	if (i == CONFIG_DLCI_MAX)
		return(-ENODEV);

	flp->dlci[i] = -abs(flp->dlci[i]);

	if (netif_running(slave) && (flp->config.station == FRAD_STATION_NODE))
		sdla_cmd(slave, SDLA_DEACTIVATE_DLCI, 0, 0, &flp->dlci[i], sizeof(short), NULL, NULL);

	return(0);
}

static int sdla_assoc(struct net_device *slave, struct net_device *master)
{
	struct frad_local *flp;
	int               i;

	if (master->type != ARPHRD_DLCI)
		return(-EINVAL);

	flp = netdev_priv(slave);

	for(i=0;i<CONFIG_DLCI_MAX;i++)
	{
		if (!flp->master[i])
			break;
		if (abs(flp->dlci[i]) == *(short *)(master->dev_addr))
			return(-EADDRINUSE);
	} 

	if (i == CONFIG_DLCI_MAX)
		return(-EMLINK);  /* #### Alan: Comments on this ?? */


	flp->master[i] = master;
	flp->dlci[i] = -*(short *)(master->dev_addr);
	master->mtu = slave->mtu;

	if (netif_running(slave)) {
		if (flp->config.station == FRAD_STATION_CPE)
			sdla_reconfig(slave);
		else
			sdla_cmd(slave, SDLA_ADD_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
	}

	return(0);
}

static int sdla_deassoc(struct net_device *slave, struct net_device *master)
{
	struct frad_local *flp;
	int               i;

	flp = netdev_priv(slave);

	for(i=0;i<CONFIG_DLCI_MAX;i++)
		if (flp->master[i] == master)
			break;

	if (i == CONFIG_DLCI_MAX)
		return(-ENODEV);

	flp->master[i] = NULL;
	flp->dlci[i] = 0;


	if (netif_running(slave)) {
		if (flp->config.station == FRAD_STATION_CPE)
			sdla_reconfig(slave);
		else
			sdla_cmd(slave, SDLA_DELETE_DLCI, 0, 0, master->dev_addr, sizeof(short), NULL, NULL);
	}

	return(0);
}

static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
{
	struct frad_local *flp;
	struct dlci_local *dlp;
	int               i;
	short             len, ret;

	flp = netdev_priv(slave);

	for(i=0;i<CONFIG_DLCI_MAX;i++)
		if (flp->master[i] == master)
			break;

	if (i == CONFIG_DLCI_MAX)
		return(-ENODEV);

	dlp = netdev_priv(master);

	ret = SDLA_RET_OK;
	len = sizeof(struct dlci_conf);
	if (netif_running(slave)) {
		if (get)
			ret = sdla_cmd(slave, SDLA_READ_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0,  
			            NULL, 0, &dlp->config, &len);
		else
			ret = sdla_cmd(slave, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0,  
			            &dlp->config, sizeof(struct dlci_conf) - 4 * sizeof(short), NULL, NULL);
	}

	return(ret == SDLA_RET_OK ? 0 : -EIO);
}

/**************************
 *
 * now for the Linux driver 
 *
 **************************/

/* NOTE: the DLCI driver deals with freeing the SKB!! */
static int sdla_transmit(struct sk_buff *skb, struct net_device *dev)
{
	struct frad_local *flp;
	int               ret, addr, accept, i;
	short             size;
	unsigned long     flags;
	struct buf_entry  *pbuf;

	flp = netdev_priv(dev);
	ret = 0;
	accept = 1;

	netif_stop_queue(dev);

	/*
	 * stupid GateD insists on setting up the multicast router thru us
	 * and we're ill equipped to handle a non Frame Relay packet at this
	 * time!
	 */

	accept = 1;
	switch (dev->type)
	{
		case ARPHRD_FRAD:
			if (skb->dev->type != ARPHRD_DLCI)
			{
				printk(KERN_WARNING "%s: Non DLCI device, type %i, tried to send on FRAD module.\n", dev->name, skb->dev->type);
				accept = 0;
			}
			break;
		default:
			printk(KERN_WARNING "%s: unknown firmware type 0x%4.4X\n", dev->name, dev->type);
			accept = 0;
			break;
	}
	if (accept)
	{
		/* this is frame specific, but till there's a PPP module, it's the default */
		switch (flp->type)
		{
			case SDLA_S502A:
			case SDLA_S502E:
				ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, skb->data, skb->len, NULL, NULL);
				break;
				case SDLA_S508:
				size = sizeof(addr);
				ret = sdla_cmd(dev, SDLA_INFORMATION_WRITE, *(short *)(skb->dev->dev_addr), 0, NULL, skb->len, &addr, &size);
				if (ret == SDLA_RET_OK)
				{

					spin_lock_irqsave(&sdla_lock, flags);
					SDLA_WINDOW(dev, addr);
					pbuf = (void *)(((int) dev->mem_start) + (addr & SDLA_ADDR_MASK));
					__sdla_write(dev, pbuf->buf_addr, skb->data, skb->len);
					SDLA_WINDOW(dev, addr);
					pbuf->opp_flag = 1;
					spin_unlock_irqrestore(&sdla_lock, flags);
				}
				break;
		}
		switch (ret)
		{
			case SDLA_RET_OK:
				flp->stats.tx_packets++;
				ret = DLCI_RET_OK;
				break;

			case SDLA_RET_CIR_OVERFLOW:
			case SDLA_RET_BUF_OVERSIZE:
			case SDLA_RET_NO_BUFS:
				flp->stats.tx_dropped++;
				ret = DLCI_RET_DROP;
				break;

			default:
				flp->stats.tx_errors++;
				ret = DLCI_RET_ERR;
				break;
		}
	}
	netif_wake_queue(dev);
	for(i=0;i<CONFIG_DLCI_MAX;i++)
	{
		if(flp->master[i]!=NULL)
			netif_wake_queue(flp->master[i]);
	}		
	return(ret);
}

static void sdla_receive(struct net_device *dev)
{
	struct net_device	  *master;
	struct frad_local *flp;
	struct dlci_local *dlp;
	struct sk_buff	 *skb;

	struct sdla_cmd	*cmd;
	struct buf_info	*pbufi;
	struct buf_entry  *pbuf;

	unsigned long	  flags;
	int               i=0, received, success, addr, buf_base, buf_top;
	short             dlci, len, len2, split;

	flp = netdev_priv(dev);
	success = 1;
	received = addr = buf_top = buf_base = 0;
	len = dlci = 0;
	skb = NULL;
	master = NULL;
	cmd = NULL;
	pbufi = NULL;
	pbuf = NULL;

	spin_lock_irqsave(&sdla_lock, flags);

	switch (flp->type)
	{
		case SDLA_S502A:
		case SDLA_S502E:
			cmd = (void *) (dev->mem_start + (SDLA_502_RCV_BUF & SDLA_ADDR_MASK));
			SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
			success = cmd->opp_flag;
			if (!success)
				break;

			dlci = cmd->dlci;
			len = cmd->length;
			break;

		case SDLA_S508:
			pbufi = (void *) (dev->mem_start + (SDLA_508_RXBUF_INFO & SDLA_ADDR_MASK));
			SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
			pbuf = (void *) (dev->mem_start + ((pbufi->rse_base + flp->buffer * sizeof(struct buf_entry)) & SDLA_ADDR_MASK));
			success = pbuf->opp_flag;
			if (!success)
				break;

			buf_top = pbufi->buf_top;
			buf_base = pbufi->buf_base;
			dlci = pbuf->dlci;
			len = pbuf->length;
			addr = pbuf->buf_addr;
			break;
	}

	/* common code, find the DLCI and get the SKB */
	if (success)
	{
		for (i=0;i<CONFIG_DLCI_MAX;i++)
			if (flp->dlci[i] == dlci)
				break;

		if (i == CONFIG_DLCI_MAX)
		{
			printk(KERN_NOTICE "%s: Received packet from invalid DLCI %i, ignoring.", dev->name, dlci);
			flp->stats.rx_errors++;
			success = 0;
		}
	}

	if (success)
	{
		master = flp->master[i];
		skb = dev_alloc_skb(len + sizeof(struct frhdr));
		if (skb == NULL) 
		{
			printk(KERN_NOTICE "%s: Memory squeeze, dropping packet.\n", dev->name);
			flp->stats.rx_dropped++; 
			success = 0;
		}
		else
			skb_reserve(skb, sizeof(struct frhdr));
	}

	/* pick up the data */
	switch (flp->type)
	{
		case SDLA_S502A:
		case SDLA_S502E:
			if (success)
				__sdla_read(dev, SDLA_502_RCV_BUF + SDLA_502_DATA_OFS, skb_put(skb,len), len);

			SDLA_WINDOW(dev, SDLA_502_RCV_BUF);
			cmd->opp_flag = 0;
			break;

		case SDLA_S508:
			if (success)
			{
				/* is this buffer split off the end of the internal ring buffer */
				split = addr + len > buf_top + 1 ? len - (buf_top - addr + 1) : 0;
				len2 = len - split;

				__sdla_read(dev, addr, skb_put(skb, len2), len2);
				if (split)
					__sdla_read(dev, buf_base, skb_put(skb, split), split);
			}

			/* increment the buffer we're looking at */
			SDLA_WINDOW(dev, SDLA_508_RXBUF_INFO);
			flp->buffer = (flp->buffer + 1) % pbufi->rse_num;
			pbuf->opp_flag = 0;
			break;
	}

	if (success)
	{
		flp->stats.rx_packets++;
		dlp = netdev_priv(master);
		(*dlp->receive)(skb, master);
	}

	spin_unlock_irqrestore(&sdla_lock, flags);
}

static irqreturn_t sdla_isr(int dummy, void *dev_id)
{
	struct net_device     *dev;
	struct frad_local *flp;
	char              byte;

	dev = dev_id;

	flp = netdev_priv(dev);

	if (!flp->initialized)
	{
		printk(KERN_WARNING "%s: irq %d for uninitialized device.\n",
		       dev->name, dev->irq);
		return IRQ_NONE;
	}

	byte = sdla_byte(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE);
	switch (byte)
	{
		case SDLA_INTR_RX:
			sdla_receive(dev);
			break;

		/* the command will get an error return, which is processed above */
		case SDLA_INTR_MODEM:
		case SDLA_INTR_STATUS:
			sdla_cmd(dev, SDLA_READ_DLC_STATUS, 0, 0, NULL, 0, NULL, NULL);
			break;

		case SDLA_INTR_TX:
		case SDLA_INTR_COMPLETE:
		case SDLA_INTR_TIMER:
			printk(KERN_WARNING "%s: invalid irq flag 0x%02X.\n", dev->name, byte);
			break;
	}

	/* the S502E requires a manual acknowledgement of the interrupt */ 
	if (flp->type == SDLA_S502E)
	{
		flp->state &= ~SDLA_S502E_INTACK;
		outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
		flp->state |= SDLA_S502E_INTACK;
		outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
	}

	/* this clears the byte, informing the Z80 we're done */
	byte = 0;
	sdla_write(dev, flp->type == SDLA_S508 ? SDLA_508_IRQ_INTERFACE : SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
	return IRQ_HANDLED;
}

static void sdla_poll(unsigned long device)
{
	struct net_device	  *dev;
	struct frad_local *flp;

	dev = (struct net_device *) device;
	flp = netdev_priv(dev);

	if (sdla_byte(dev, SDLA_502_RCV_BUF))
		sdla_receive(dev);

	flp->timer.expires = 1;
	add_timer(&flp->timer);
}

static int sdla_close(struct net_device *dev)
{
	struct frad_local *flp;
	struct intr_info  intr;
	int               len, i;
	short             dlcis[CONFIG_DLCI_MAX];

	flp = netdev_priv(dev);

	len = 0;
	for(i=0;i<CONFIG_DLCI_MAX;i++)
		if (flp->dlci[i])
			dlcis[len++] = abs(flp->dlci[i]);
	len *= 2;

	if (flp->config.station == FRAD_STATION_NODE)
	{
		for(i=0;i<CONFIG_DLCI_MAX;i++)
			if (flp->dlci[i] > 0) 
				sdla_cmd(dev, SDLA_DEACTIVATE_DLCI, 0, 0, dlcis, len, NULL, NULL);
		sdla_cmd(dev, SDLA_DELETE_DLCI, 0, 0, &flp->dlci[i], sizeof(flp->dlci[i]), NULL, NULL);
	}

	memset(&intr, 0, sizeof(intr));
	/* let's start up the reception */
	switch(flp->type)
	{
		case SDLA_S502A:
			del_timer(&flp->timer); 
			break;

		case SDLA_S502E:
			sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
			flp->state &= ~SDLA_S502E_INTACK;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			break;

		case SDLA_S507:
			break;

		case SDLA_S508:
			sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
			flp->state &= ~SDLA_S508_INTEN;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			break;
	}

	sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);

	netif_stop_queue(dev);
	
	return(0);
}

struct conf_data {
	struct frad_conf config;
	short            dlci[CONFIG_DLCI_MAX];
};

static int sdla_open(struct net_device *dev)
{
	struct frad_local *flp;
	struct dlci_local *dlp;
	struct conf_data  data;
	struct intr_info  intr;
	int               len, i;
	char              byte;

	flp = netdev_priv(dev);

	if (!flp->initialized)
		return(-EPERM);

	if (!flp->configured)
		return(-EPERM);

	/* time to send in the configuration */
	len = 0;
	for(i=0;i<CONFIG_DLCI_MAX;i++)
		if (flp->dlci[i])
			data.dlci[len++] = abs(flp->dlci[i]);
	len *= 2;

	memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
	len += sizeof(struct frad_conf);

	sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
	sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);

	if (flp->type == SDLA_S508)
		flp->buffer = 0;

	sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);

	/* let's start up the reception */
	memset(&intr, 0, sizeof(intr));
	switch(flp->type)
	{
		case SDLA_S502A:
			flp->timer.expires = 1;
			add_timer(&flp->timer);
			break;

		case SDLA_S502E:
			flp->state |= SDLA_S502E_ENABLE;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			flp->state |= SDLA_S502E_INTACK;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			byte = 0;
			sdla_write(dev, SDLA_502_IRQ_INTERFACE, &byte, sizeof(byte));
			intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
			sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(char) + sizeof(short), NULL, NULL);
			break;

		case SDLA_S507:
			break;

		case SDLA_S508:
			flp->state |= SDLA_S508_INTEN;
			outb(flp->state, dev->base_addr + SDLA_REG_CONTROL);
			byte = 0;
			sdla_write(dev, SDLA_508_IRQ_INTERFACE, &byte, sizeof(byte));
			intr.flags = SDLA_INTR_RX | SDLA_INTR_STATUS | SDLA_INTR_MODEM;
			intr.irq = dev->irq;
			sdla_cmd(dev, SDLA_SET_IRQ_TRIGGER, 0, 0, &intr, sizeof(struct intr_info), NULL, NULL);
			break;
	}

	if (flp->config.station == FRAD_STATION_CPE)
	{
		byte = SDLA_ICS_STATUS_ENQ;
		sdla_cmd(dev, SDLA_ISSUE_IN_CHANNEL_SIGNAL, 0, 0, &byte, sizeof(byte), NULL, NULL);
	}
	else
	{
		sdla_cmd(dev, SDLA_ADD_DLCI, 0, 0, data.dlci, len - sizeof(struct frad_conf), NULL, NULL);
		for(i=0;i<CONFIG_DLCI_MAX;i++)
			if (flp->dlci[i] > 0)
				sdla_cmd(dev, SDLA_ACTIVATE_DLCI, 0, 0, &flp->dlci[i], 2*sizeof(flp->dlci[i]), NULL, NULL);
	}

	/* configure any specific DLCI settings */
	for(i=0;i<CONFIG_DLCI_MAX;i++)
		if (flp->dlci[i])
		{
			dlp = netdev_priv(flp->master[i]);
			if (dlp->configured)
				sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, abs(flp->dlci[i]), 0, &dlp->config, sizeof(struct dlci_conf), NULL, NULL);
		}

	netif_start_queue(dev);
	
	return(0);
}

static int sdla_config(struct net_device *dev, struct frad_conf __user *conf, int get)
{
	struct frad_local *flp;
	struct conf_data  data;
	int               i;
	short             size;

	if (dev->type == 0xFFFF)
		return(-EUNATCH);

	flp = netdev_priv(dev);

	if (!get)
	{
		if (netif_running(dev))
			return(-EBUSY);

		if(copy_from_user(&data.config, conf, sizeof(struct frad_conf)))
			return -EFAULT;

		if (data.config.station & ~FRAD_STATION_NODE)
			return(-EINVAL);

		if (data.config.flags & ~FRAD_VALID_FLAGS)
			return(-EINVAL);

		if ((data.config.kbaud < 0) || 
			 ((data.config.kbaud > 128) && (flp->type != SDLA_S508)))
			return(-EINVAL);

		if (data.config.clocking & ~(FRAD_CLOCK_INT | SDLA_S508_PORT_RS232))
			return(-EINVAL);

		if ((data.config.mtu < 0) || (data.config.mtu > SDLA_MAX_MTU))
			return(-EINVAL);

		if ((data.config.T391 < 5) || (data.config.T391 > 30))
			return(-EINVAL);

		if ((data.config.T392 < 5) || (data.config.T392 > 30))
			return(-EINVAL);

		if ((data.config.N391 < 1) || (data.config.N391 > 255))
			return(-EINVAL);

		if ((data.config.N392 < 1) || (data.config.N392 > 10))
			return(-EINVAL);

		if ((data.config.N393 < 1) || (data.config.N393 > 10))
			return(-EINVAL);

		memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
		flp->config.flags |= SDLA_DIRECT_RECV;

		if (flp->type == SDLA_S508)
			flp->config.flags |= SDLA_TX70_RX30;

		if (dev->mtu != flp->config.mtu)
		{
			/* this is required to change the MTU */
			dev->mtu = flp->config.mtu;
			for(i=0;i<CONFIG_DLCI_MAX;i++)
				if (flp->master[i])
					flp->master[i]->mtu = flp->config.mtu;
		}

		flp->config.mtu += sizeof(struct frhdr);

		/* off to the races! */
		if (!flp->configured)
			sdla_start(dev);

		flp->configured = 1;
	}
	else
	{
		/* no sense reading if the CPU isn't started */
		if (netif_running(dev))
		{
			size = sizeof(data);
			if (sdla_cmd(dev, SDLA_READ_DLCI_CONFIGURATION, 0, 0, NULL, 0, &data, &size) != SDLA_RET_OK)
				return(-EIO);
		}
		else
			if (flp->configured)
				memcpy(&data.config, &flp->config, sizeof(struct frad_conf));
			else
				memset(&data.config, 0, sizeof(struct frad_conf));

		memcpy(&flp->config, &data.config, sizeof(struct frad_conf));
		data.config.flags &= FRAD_VALID_FLAGS;
		data.config.mtu -= data.config.mtu > sizeof(struct frhdr) ? sizeof(struct frhdr) : data.config.mtu;
		return copy_to_user(conf, &data.config, sizeof(struct frad_conf))?-EFAULT:0;
	}

	return(0);
}

static int sdla_xfer(struct net_device *dev, struct sdla_mem __user *info, int read)
{
	struct sdla_mem mem;
	char	*temp;

	if(copy_from_user(&mem, info, sizeof(mem)))
		return -EFAULT;
		
	if (read)
	{	
		temp = kzalloc(mem.len, GFP_KERNEL);
		if (!temp)
			return(-ENOMEM);
		sdla_read(dev, mem.addr, temp, mem.len);
		if(copy_to_user(mem.data, temp, mem.len))
		{
			kfree(temp);
			return -EFAULT;
		}
		kfree(temp);
	}
	else
	{
		temp = kmalloc(mem.len, GFP_KERNEL);
		if (!temp)
			return(-ENOMEM);
		if(copy_from_user(temp, mem.data, mem.len))
		{
			kfree(temp);
			return -EFAULT;
		}
		sdla_write(dev, mem.addr, temp, mem.len);
		kfree(temp);
	}
	return(0);
}

static int sdla_reconfig(struct net_device *dev)
{
	struct frad_local *flp;
	struct conf_data  data;
	int               i, len;

	flp = netdev_priv(dev);

	len = 0;
	for(i=0;i<CONFIG_DLCI_MAX;i++)
		if (flp->dlci[i])
			data.dlci[len++] = flp->dlci[i];
	len *= 2;

	memcpy(&data, &flp->config, sizeof(struct frad_conf));
	len += sizeof(struct frad_conf);

	sdla_cmd(dev, SDLA_DISABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);
	sdla_cmd(dev, SDLA_SET_DLCI_CONFIGURATION, 0, 0, &data, len, NULL, NULL);
	sdla_cmd(dev, SDLA_ENABLE_COMMUNICATIONS, 0, 0, NULL, 0, NULL, NULL);

	return(0);
}

static int sdla_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
	struct frad_local *flp;

	if(!capable(CAP_NET_ADMIN))
		return -EPERM;
		
	flp = netdev_priv(dev);

	if (!flp->initialized)
		return(-EINVAL);

	switch (cmd)
	{
		case FRAD_GET_CONF:
		case FRAD_SET_CONF:
			return(sdla_config(dev, ifr->ifr_data, cmd == FRAD_GET_CONF));

		case SDLA_IDENTIFY:
			ifr->ifr_flags = flp->type;
			break;

		case SDLA_CPUSPEED:
			return(sdla_cpuspeed(dev, ifr)); 

/* ==========================================================
NOTE:  This is rather a useless action right now, as the
       current driver does not support protocols other than
       FR.  However, Sangoma has modules for a number of
       other protocols in the works.
============================================================*/
		case SDLA_PROTOCOL:
			if (flp->configured)
				return(-EALREADY);

			switch (ifr->ifr_flags)
			{
				case ARPHRD_FRAD:
					dev->type = ifr->ifr_flags;
					break;
				default:
					return(-ENOPROTOOPT);
			}
			break;

		case SDLA_CLEARMEM:
			sdla_clear(dev);
			break;

		case SDLA_WRITEMEM:
		case SDLA_READMEM:
			if(!capable(CAP_SYS_RAWIO))
				return -EPERM;
			return(sdla_xfer(dev, ifr->ifr_data, cmd == SDLA_READMEM));

		case SDLA_START:
			sdla_start(dev);
			break;

		case SDLA_STOP:
			sdla_stop(dev);
			break;

		default:
			return(-EOPNOTSUPP);
	}
	return(0);
}

static int sdla_change_mtu(struct net_device *dev, int new_mtu)
{
	struct frad_local *flp;

	flp = netdev_priv(dev);

	if (netif_running(dev))
		return(-EBUSY);

	/* for now, you can't change the MTU! */
	return(-EOPNOTSUPP);
}

static int sdla_set_config(struct net_device *dev, struct ifmap *map)
{
	struct frad_local *flp;
	int               i;
	char              byte;
	unsigned base;
	int err = -EINVAL;

	flp = netdev_priv(dev);

	if (flp->initialized)
		return(-EINVAL);

	for(i=0; i < ARRAY_SIZE(valid_port); i++)
		if (valid_port[i] == map->base_addr)
			break;   

	if (i == ARRAY_SIZE(valid_port))
		return(-EINVAL);

	if (!request_region(map->base_addr, SDLA_IO_EXTENTS, dev->name)){
		printk(KERN_WARNING "SDLA: io-port 0x%04lx in use \n", dev->base_addr);
		return(-EINVAL);
	}
	base = map->base_addr;

	/* test for card types, S502A, S502E, S507, S508                 */
	/* these tests shut down the card completely, so clear the state */
	flp->type = SDLA_UNKNOWN;
	flp->state = 0;
   
	for(i=1;i<SDLA_IO_EXTENTS;i++)
		if (inb(base + i) != 0xFF)
			break;

	if (i == SDLA_IO_EXTENTS) {   
		outb(SDLA_HALT, base + SDLA_REG_Z80_CONTROL);
		if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x08) {
			outb(SDLA_S502E_INTACK, base + SDLA_REG_CONTROL);
			if ((inb(base + SDLA_S502_STS) & 0x0F) == 0x0C) {
				outb(SDLA_HALT, base + SDLA_REG_CONTROL);
				flp->type = SDLA_S502E;
				goto got_type;
			}
		}
	}

	for(byte=inb(base),i=0;i<SDLA_IO_EXTENTS;i++)
		if (inb(base + i) != byte)
			break;

	if (i == SDLA_IO_EXTENTS) {
		outb(SDLA_HALT, base + SDLA_REG_CONTROL);
		if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x30) {
			outb(SDLA_S507_ENABLE, base + SDLA_REG_CONTROL);
			if ((inb(base + SDLA_S502_STS) & 0x7E) == 0x32) {
				outb(SDLA_HALT, base + SDLA_REG_CONTROL);
				flp->type = SDLA_S507;
				goto got_type;
			}
		}
	}

	outb(SDLA_HALT, base + SDLA_REG_CONTROL);
	if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x00) {
		outb(SDLA_S508_INTEN, base + SDLA_REG_CONTROL);
		if ((inb(base + SDLA_S508_STS) & 0x3F) == 0x10) {
			outb(SDLA_HALT, base + SDLA_REG_CONTROL);
			flp->type = SDLA_S508;
			goto got_type;
		}
	}

	outb(SDLA_S502A_HALT, base + SDLA_REG_CONTROL);
	if (inb(base + SDLA_S502_STS) == 0x40) {
		outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
		if (inb(base + SDLA_S502_STS) == 0x40) {
			outb(SDLA_S502A_INTEN, base + SDLA_REG_CONTROL);
			if (inb(base + SDLA_S502_STS) == 0x44) {
				outb(SDLA_S502A_START, base + SDLA_REG_CONTROL);
				flp->type = SDLA_S502A;
				goto got_type;
			}
		}
	}

	printk(KERN_NOTICE "%s: Unknown card type\n", dev->name);
	err = -ENODEV;
	goto fail;

got_type:
	switch(base) {
		case 0x270:
		case 0x280:
		case 0x380: 
		case 0x390:
			if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
				goto fail;
	}

	switch (map->irq) {
		case 2:
			if (flp->type != SDLA_S502E)
				goto fail;
			break;

		case 10:
		case 11:
		case 12:
		case 15:
		case 4:
			if (flp->type != SDLA_S508 && flp->type != SDLA_S507)
				goto fail;
			break;
		case 3:
		case 5:
		case 7:
			if (flp->type == SDLA_S502A)
				goto fail;
			break;

		default:
			goto fail;
	}

	err = -EAGAIN;
	if (request_irq(dev->irq, &sdla_isr, 0, dev->name, dev)) 
		goto fail;

	if (flp->type == SDLA_S507) {
		switch(dev->irq) {
			case 3:
				flp->state = SDLA_S507_IRQ3;
				break;
			case 4:
				flp->state = SDLA_S507_IRQ4;
				break;
			case 5:
				flp->state = SDLA_S507_IRQ5;
				break;
			case 7:
				flp->state = SDLA_S507_IRQ7;
				break;
			case 10:
				flp->state = SDLA_S507_IRQ10;
				break;
			case 11:
				flp->state = SDLA_S507_IRQ11;
				break;
			case 12:
				flp->state = SDLA_S507_IRQ12;
				break;
			case 15:
				flp->state = SDLA_S507_IRQ15;
				break;
		}
	}

	for(i=0; i < ARRAY_SIZE(valid_mem); i++)
		if (valid_mem[i] == map->mem_start)
			break;   

	err = -EINVAL;
	if (i == ARRAY_SIZE(valid_mem))
		goto fail2;

	if (flp->type == SDLA_S502A && (map->mem_start & 0xF000) >> 12 == 0x0E)
		goto fail2;

	if (flp->type != SDLA_S507 && map->mem_start >> 16 == 0x0B)
		goto fail2;

	if (flp->type == SDLA_S507 && map->mem_start >> 16 == 0x0D)
		goto fail2;

	byte = flp->type != SDLA_S508 ? SDLA_8K_WINDOW : 0;
	byte |= (map->mem_start & 0xF000) >> (12 + (flp->type == SDLA_S508 ? 1 : 0));
	switch(flp->type) {
		case SDLA_S502A:
		case SDLA_S502E:
			switch (map->mem_start >> 16) {
				case 0x0A:
					byte |= SDLA_S502_SEG_A;
					break;
				case 0x0C:
					byte |= SDLA_S502_SEG_C;
					break;
				case 0x0D:
					byte |= SDLA_S502_SEG_D;
					break;
				case 0x0E:
					byte |= SDLA_S502_SEG_E;
					break;
			}
			break;
		case SDLA_S507:
			switch (map->mem_start >> 16) {
				case 0x0A:
					byte |= SDLA_S507_SEG_A;
					break;
				case 0x0B:
					byte |= SDLA_S507_SEG_B;
					break;
				case 0x0C:
					byte |= SDLA_S507_SEG_C;
					break;
				case 0x0E:
					byte |= SDLA_S507_SEG_E;
					break;
			}
			break;
		case SDLA_S508:
			switch (map->mem_start >> 16) {
				case 0x0A:
					byte |= SDLA_S508_SEG_A;
					break;
				case 0x0C:
					byte |= SDLA_S508_SEG_C;
					break;
				case 0x0D:
					byte |= SDLA_S508_SEG_D;
					break;
				case 0x0E:
					byte |= SDLA_S508_SEG_E;
					break;
			}
			break;
	}

	/* set the memory bits, and enable access */
	outb(byte, base + SDLA_REG_PC_WINDOW);

	switch(flp->type)
	{
		case SDLA_S502E:
			flp->state = SDLA_S502E_ENABLE;
			break;
		case SDLA_S507:
			flp->state |= SDLA_MEMEN;
			break;
		case SDLA_S508:
			flp->state = SDLA_MEMEN;
			break;
	}
	outb(flp->state, base + SDLA_REG_CONTROL);

	dev->irq = map->irq;
	dev->base_addr = base;
	dev->mem_start = map->mem_start;
	dev->mem_end = dev->mem_start + 0x2000;
	flp->initialized = 1;
	return 0;

fail2:
	free_irq(map->irq, dev);
fail:
	release_region(base, SDLA_IO_EXTENTS);
	return err;
}
 
static struct net_device_stats *sdla_stats(struct net_device *dev)
{
	struct frad_local *flp;
	flp = netdev_priv(dev);

	return(&flp->stats);
}

static void setup_sdla(struct net_device *dev)
{
	struct frad_local *flp = netdev_priv(dev);

	netdev_boot_setup_check(dev);

	dev->flags		= 0;
	dev->type		= 0xFFFF;
	dev->hard_header_len	= 0;
	dev->addr_len		= 0;
	dev->mtu		= SDLA_MAX_MTU;

	dev->open		= sdla_open;
	dev->stop		= sdla_close;
	dev->do_ioctl		= sdla_ioctl;
	dev->set_config		= sdla_set_config;
	dev->get_stats		= sdla_stats;
	dev->hard_start_xmit	= sdla_transmit;
	dev->change_mtu		= sdla_change_mtu;

	flp->activate		= sdla_activate;
	flp->deactivate		= sdla_deactivate;
	flp->assoc		= sdla_assoc;
	flp->deassoc		= sdla_deassoc;
	flp->dlci_conf		= sdla_dlci_conf;

	init_timer(&flp->timer);
	flp->timer.expires	= 1;
	flp->timer.data		= (unsigned long) dev;
	flp->timer.function	= sdla_poll;
}

static struct net_device *sdla;

static int __init init_sdla(void)
{
	int err;

	printk("%s.\n", version);

	sdla = alloc_netdev(sizeof(struct frad_local), "sdla0", setup_sdla);
	if (!sdla) 
		return -ENOMEM;

	err = register_netdev(sdla);
	if (err) 
		free_netdev(sdla);

	return err;
}

static void __exit exit_sdla(void)
{
	struct frad_local *flp = netdev_priv(sdla);

	unregister_netdev(sdla);
	if (flp->initialized) {
		free_irq(sdla->irq, sdla);
		release_region(sdla->base_addr, SDLA_IO_EXTENTS);
	}
	del_timer_sync(&flp->timer);
	free_netdev(sdla);
}

MODULE_LICENSE("GPL");

module_init(init_sdla);
module_exit(exit_sdla);
