/* Intel EtherExpress 16 device driver for Linux
 *
 * Written by John Sullivan, 1995
 *  based on original code by Donald Becker, with changes by
 *  Alan Cox and Pauline Middelink.
 *
 * Support for 8-bit mode by Zoltan Szilagyi <zoltans@cs.arizona.edu>
 *
 * Many modifications, and currently maintained, by
 *  Philip Blundell <philb@gnu.org>
 * Added the Compaq LTE  Alan Cox <alan@redhat.com>
 * Added MCA support Adam Fritzler
 *
 * Note - this driver is experimental still - it has problems on faster
 * machines. Someone needs to sit down and go through it line by line with
 * a databook...
 */

/* The EtherExpress 16 is a fairly simple card, based on a shared-memory
 * design using the i82586 Ethernet coprocessor.  It bears no relationship,
 * as far as I know, to the similarly-named "EtherExpress Pro" range.
 *
 * Historically, Linux support for these cards has been very bad.  However,
 * things seem to be getting better slowly.
 */

/* If your card is confused about what sort of interface it has (eg it
 * persistently reports "10baseT" when none is fitted), running 'SOFTSET /BART'
 * or 'SOFTSET /LISA' from DOS seems to help.
 */

/* Here's the scoop on memory mapping.
 *
 * There are three ways to access EtherExpress card memory: either using the
 * shared-memory mapping, or using PIO through the dataport, or using PIO
 * through the "shadow memory" ports.
 *
 * The shadow memory system works by having the card map some of its memory
 * as follows:
 *
 * (the low five bits of the SMPTR are ignored)
 *
 *  base+0x4000..400f      memory at SMPTR+0..15
 *  base+0x8000..800f      memory at SMPTR+16..31
 *  base+0xc000..c007      dubious stuff (memory at SMPTR+16..23 apparently)
 *  base+0xc008..c00f      memory at 0x0008..0x000f
 *
 * This last set (the one at c008) is particularly handy because the SCB
 * lives at 0x0008.  So that set of ports gives us easy random access to data
 * in the SCB without having to mess around setting up pointers and the like.
 * We always use this method to access the SCB (via the scb_xx() functions).
 *
 * Dataport access works by aiming the appropriate (read or write) pointer
 * at the first address you're interested in, and then reading or writing from
 * the dataport.  The pointers auto-increment after each transfer.  We use
 * this for data transfer.
 *
 * We don't use the shared-memory system because it allegedly doesn't work on
 * all cards, and because it's a bit more prone to go wrong (it's one more
 * thing to configure...).
 */

/* Known bugs:
 *
 * - The card seems to want to give us two interrupts every time something
 *   happens, where just one would be better.
 */

/*
 *
 * Note by Zoltan Szilagyi 10-12-96:
 *
 * I've succeeded in eliminating the "CU wedged" messages, and hence the
 * lockups, which were only occurring with cards running in 8-bit mode ("force
 * 8-bit operation" in Intel's SoftSet utility). This version of the driver
 * sets the 82586 and the ASIC to 8-bit mode at startup; it also stops the
 * CU before submitting a packet for transmission, and then restarts it as soon
 * as the process of handing the packet is complete. This is definitely an
 * unnecessary slowdown if the card is running in 16-bit mode; therefore one
 * should detect 16-bit vs 8-bit mode from the EEPROM settings and act
 * accordingly. In 8-bit mode with this bugfix I'm getting about 150 K/s for
 * ftp's, which is significantly better than I get in DOS, so the overhead of
 * stopping and restarting the CU with each transmit is not prohibitive in
 * practice.
 *
 * Update by David Woodhouse 11/5/99:
 *
 * I've seen "CU wedged" messages in 16-bit mode, on the Alpha architecture.
 * I assume that this is because 16-bit accesses are actually handled as two
 * 8-bit accesses.
 */

#ifdef __alpha__
#define LOCKUP16 1
#endif
#ifndef LOCKUP16
#define LOCKUP16 0
#endif

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/string.h>
#include <linux/in.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/mca-legacy.h>
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/irq.h>

#ifndef NET_DEBUG
#define NET_DEBUG 4
#endif

#include "eexpress.h"

#define EEXP_IO_EXTENT  16

/*
 * Private data declarations
 */

struct net_local
{
	unsigned long last_tx;       /* jiffies when last transmit started */
	unsigned long init_time;     /* jiffies when eexp_hw_init586 called */
	unsigned short rx_first;     /* first rx buf, same as RX_BUF_START */
	unsigned short rx_last;      /* last rx buf */
	unsigned short rx_ptr;       /* first rx buf to look at */
	unsigned short tx_head;      /* next free tx buf */
	unsigned short tx_reap;      /* first in-use tx buf */
	unsigned short tx_tail;      /* previous tx buf to tx_head */
	unsigned short tx_link;      /* last known-executing tx buf */
	unsigned short last_tx_restart;   /* set to tx_link when we
					     restart the CU */
	unsigned char started;
	unsigned short rx_buf_start;
	unsigned short rx_buf_end;
	unsigned short num_tx_bufs;
	unsigned short num_rx_bufs;
	unsigned char width;         /* 0 for 16bit, 1 for 8bit */
	unsigned char was_promisc;
	unsigned char old_mc_count;
	spinlock_t lock;
};

/* This is the code and data that is downloaded to the EtherExpress card's
 * memory at boot time.
 */

static unsigned short start_code[] = {
/* 0x0000 */
	0x0001,                 /* ISCP: busy - cleared after reset */
	0x0008,0x0000,0x0000,   /* offset,address (lo,hi) of SCB */

	0x0000,0x0000,          /* SCB: status, commands */
	0x0000,0x0000,          /* links to first command block,
				   first receive descriptor */
	0x0000,0x0000,          /* CRC error, alignment error counts */
	0x0000,0x0000,          /* out of resources, overrun error counts */

	0x0000,0x0000,          /* pad */
	0x0000,0x0000,

/* 0x20 -- start of 82586 CU program */
#define CONF_LINK 0x20
	0x0000,Cmd_Config,
	0x0032,                 /* link to next command */
	0x080c,                 /* 12 bytes follow : fifo threshold=8 */
	0x2e40,                 /* don't rx bad frames
				 * SRDY/ARDY => ext. sync. : preamble len=8
	                         * take addresses from data buffers
				 * 6 bytes/address
				 */
	0x6000,                 /* default backoff method & priority
				 * interframe spacing = 0x60 */
	0xf200,                 /* slot time=0x200
				 * max collision retry = 0xf */
#define CONF_PROMISC  0x2e
	0x0000,                 /* no HDLC : normal CRC : enable broadcast
				 * disable promiscuous/multicast modes */
	0x003c,                 /* minimum frame length = 60 octets) */

	0x0000,Cmd_SetAddr,
	0x003e,                 /* link to next command */
#define CONF_HWADDR  0x38
	0x0000,0x0000,0x0000,   /* hardware address placed here */

	0x0000,Cmd_MCast,
	0x0076,                 /* link to next command */
#define CONF_NR_MULTICAST 0x44
	0x0000,                 /* number of multicast addresses */
#define CONF_MULTICAST 0x46
	0x0000, 0x0000, 0x0000, /* some addresses */
	0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000,
	0x0000, 0x0000, 0x0000,

#define CONF_DIAG_RESULT  0x76
	0x0000, Cmd_Diag,
	0x007c,                 /* link to next command */

	0x0000,Cmd_TDR|Cmd_INT,
	0x0084,
#define CONF_TDR_RESULT  0x82
	0x0000,

	0x0000,Cmd_END|Cmd_Nop, /* end of configure sequence */
	0x0084                  /* dummy link */
};

/* maps irq number to EtherExpress magic value */
static char irqrmap[] = { 0,0,1,2,3,4,0,0,0,1,5,6,0,0,0,0 };

#ifdef CONFIG_MCA_LEGACY
/* mapping of the first four bits of the second POS register */
static unsigned short mca_iomap[] = {
	0x270, 0x260, 0x250, 0x240, 0x230, 0x220, 0x210, 0x200,
	0x370, 0x360, 0x350, 0x340, 0x330, 0x320, 0x310, 0x300
};
/* bits 5-7 of the second POS register */
static char mca_irqmap[] = { 12, 9, 3, 4, 5, 10, 11, 15 };
#endif

/*
 * Prototypes for Linux interface
 */

static int eexp_open(struct net_device *dev);
static int eexp_close(struct net_device *dev);
static void eexp_timeout(struct net_device *dev);
static int eexp_xmit(struct sk_buff *buf, struct net_device *dev);

static irqreturn_t eexp_irq(int irq, void *dev_addr);
static void eexp_set_multicast(struct net_device *dev);

/*
 * Prototypes for hardware access functions
 */

static void eexp_hw_rx_pio(struct net_device *dev);
static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf,
		       unsigned short len);
static int eexp_hw_probe(struct net_device *dev,unsigned short ioaddr);
static unsigned short eexp_hw_readeeprom(unsigned short ioaddr,
					 unsigned char location);

static unsigned short eexp_hw_lasttxstat(struct net_device *dev);
static void eexp_hw_txrestart(struct net_device *dev);

static void eexp_hw_txinit    (struct net_device *dev);
static void eexp_hw_rxinit    (struct net_device *dev);

static void eexp_hw_init586   (struct net_device *dev);
static void eexp_setup_filter (struct net_device *dev);

static char *eexp_ifmap[]={"AUI", "BNC", "RJ45"};
enum eexp_iftype {AUI=0, BNC=1, TPE=2};

#define STARTED_RU      2
#define STARTED_CU      1

/*
 * Primitive hardware access functions.
 */

static inline unsigned short scb_status(struct net_device *dev)
{
	return inw(dev->base_addr + 0xc008);
}

static inline unsigned short scb_rdcmd(struct net_device *dev)
{
	return inw(dev->base_addr + 0xc00a);
}

static inline void scb_command(struct net_device *dev, unsigned short cmd)
{
	outw(cmd, dev->base_addr + 0xc00a);
}

static inline void scb_wrcbl(struct net_device *dev, unsigned short val)
{
	outw(val, dev->base_addr + 0xc00c);
}

static inline void scb_wrrfa(struct net_device *dev, unsigned short val)
{
	outw(val, dev->base_addr + 0xc00e);
}

static inline void set_loopback(struct net_device *dev)
{
	outb(inb(dev->base_addr + Config) | 2, dev->base_addr + Config);
}

static inline void clear_loopback(struct net_device *dev)
{
	outb(inb(dev->base_addr + Config) & ~2, dev->base_addr + Config);
}

static inline unsigned short int SHADOW(short int addr)
{
	addr &= 0x1f;
	if (addr > 0xf) addr += 0x3ff0;
	return addr + 0x4000;
}

/*
 * Linux interface
 */

/*
 * checks for presence of EtherExpress card
 */

static int __init do_express_probe(struct net_device *dev)
{
	unsigned short *port;
	static unsigned short ports[] = { 0x240,0x300,0x310,0x270,0x320,0x340,0 };
	unsigned short ioaddr = dev->base_addr;
	int dev_irq = dev->irq;
	int err;

	dev->if_port = 0xff; /* not set */

#ifdef CONFIG_MCA_LEGACY
	if (MCA_bus) {
		int slot = 0;

		/*
		 * Only find one card at a time.  Subsequent calls
		 * will find others, however, proper multicard MCA
		 * probing and setup can't be done with the
		 * old-style Space.c init routines.  -- ASF
		 */
		while (slot != MCA_NOTFOUND) {
			int pos0, pos1;

			slot = mca_find_unused_adapter(0x628B, slot);
			if (slot == MCA_NOTFOUND)
				break;

			pos0 = mca_read_stored_pos(slot, 2);
			pos1 = mca_read_stored_pos(slot, 3);
			ioaddr = mca_iomap[pos1&0xf];

			dev->irq = mca_irqmap[(pos1>>4)&0x7];

			/*
			 * XXX: Transciever selection is done
			 * differently on the MCA version.
			 * How to get it to select something
			 * other than external/AUI is currently
			 * unknown.  This code is just for looks. -- ASF
			 */
			if ((pos0 & 0x7) == 0x1)
				dev->if_port = AUI;
			else if ((pos0 & 0x7) == 0x5) {
				if (pos1 & 0x80)
					dev->if_port = BNC;
				else
					dev->if_port = TPE;
			}

			mca_set_adapter_name(slot, "Intel EtherExpress 16 MCA");
			mca_set_adapter_procfn(slot, NULL, dev);
			mca_mark_as_used(slot);

			break;
		}
	}
#endif
	if (ioaddr&0xfe00) {
		if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress"))
			return -EBUSY;
		err = eexp_hw_probe(dev,ioaddr);
		release_region(ioaddr, EEXP_IO_EXTENT);
		return err;
	} else if (ioaddr)
		return -ENXIO;

	for (port=&ports[0] ; *port ; port++ )
	{
		unsigned short sum = 0;
		int i;
		if (!request_region(*port, EEXP_IO_EXTENT, "EtherExpress"))
			continue;
		for ( i=0 ; i<4 ; i++ )
		{
			unsigned short t;
			t = inb(*port + ID_PORT);
			sum |= (t>>4) << ((t & 0x03)<<2);
		}
		if (sum==0xbaba && !eexp_hw_probe(dev,*port)) {
			release_region(*port, EEXP_IO_EXTENT);
			return 0;
		}
		release_region(*port, EEXP_IO_EXTENT);
		dev->irq = dev_irq;
	}
	return -ENODEV;
}

#ifndef MODULE
struct net_device * __init express_probe(int unit)
{
	struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
	int err;

	if (!dev)
		return ERR_PTR(-ENOMEM);

	sprintf(dev->name, "eth%d", unit);
	netdev_boot_setup_check(dev);

	err = do_express_probe(dev);
	if (!err)
		return dev;
	free_netdev(dev);
	return ERR_PTR(err);
}
#endif

/*
 * open and initialize the adapter, ready for use
 */

static int eexp_open(struct net_device *dev)
{
	int ret;
	unsigned short ioaddr = dev->base_addr;
	struct net_local *lp = netdev_priv(dev);

#if NET_DEBUG > 6
	printk(KERN_DEBUG "%s: eexp_open()\n", dev->name);
#endif

	if (!dev->irq || !irqrmap[dev->irq])
		return -ENXIO;

	ret = request_irq(dev->irq, &eexp_irq, 0, dev->name, dev);
	if (ret)
		return ret;

	if (!request_region(ioaddr, EEXP_IO_EXTENT, "EtherExpress")) {
		printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
			, ioaddr);
		goto err_out1;
	}
	if (!request_region(ioaddr+0x4000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
		printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
			, ioaddr+0x4000);
		goto err_out2;
	}
	if (!request_region(ioaddr+0x8000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
		printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
			, ioaddr+0x8000);
		goto err_out3;
	}
	if (!request_region(ioaddr+0xc000, EEXP_IO_EXTENT, "EtherExpress shadow")) {
		printk(KERN_WARNING "EtherExpress io port %x, is busy.\n"
			, ioaddr+0xc000);
		goto err_out4;
	}

	if (lp->width) {
		printk("%s: forcing ASIC to 8-bit mode\n", dev->name);
		outb(inb(dev->base_addr+Config)&~4, dev->base_addr+Config);
	}

	eexp_hw_init586(dev);
	netif_start_queue(dev);
#if NET_DEBUG > 6
	printk(KERN_DEBUG "%s: leaving eexp_open()\n", dev->name);
#endif
	return 0;

	err_out4:
		release_region(ioaddr+0x8000, EEXP_IO_EXTENT);
	err_out3:
		release_region(ioaddr+0x4000, EEXP_IO_EXTENT);
	err_out2:
		release_region(ioaddr, EEXP_IO_EXTENT);
	err_out1:
		free_irq(dev->irq, dev);
		return -EBUSY;
}

/*
 * close and disable the interface, leaving the 586 in reset.
 */

static int eexp_close(struct net_device *dev)
{
	unsigned short ioaddr = dev->base_addr;
	struct net_local *lp = netdev_priv(dev);

	int irq = dev->irq;

	netif_stop_queue(dev);

	outb(SIRQ_dis|irqrmap[irq],ioaddr+SET_IRQ);
	lp->started = 0;
	scb_command(dev, SCB_CUsuspend|SCB_RUsuspend);
	outb(0,ioaddr+SIGNAL_CA);
	free_irq(irq,dev);
	outb(i586_RST,ioaddr+EEPROM_Ctrl);
	release_region(ioaddr, EEXP_IO_EXTENT);
	release_region(ioaddr+0x4000, 16);
	release_region(ioaddr+0x8000, 16);
	release_region(ioaddr+0xc000, 16);

	return 0;
}

/*
 * This gets called when a higher level thinks we are broken.  Check that
 * nothing has become jammed in the CU.
 */

static void unstick_cu(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned short ioaddr = dev->base_addr;

	if (lp->started)
	{
		if (time_after(jiffies, dev->trans_start + 50))
		{
			if (lp->tx_link==lp->last_tx_restart)
			{
				unsigned short boguscount=200,rsst;
				printk(KERN_WARNING "%s: Retransmit timed out, status %04x, resetting...\n",
				       dev->name, scb_status(dev));
				eexp_hw_txinit(dev);
				lp->last_tx_restart = 0;
				scb_wrcbl(dev, lp->tx_link);
				scb_command(dev, SCB_CUstart);
				outb(0,ioaddr+SIGNAL_CA);
				while (!SCB_complete(rsst=scb_status(dev)))
				{
					if (!--boguscount)
					{
						boguscount=200;
						printk(KERN_WARNING "%s: Reset timed out status %04x, retrying...\n",
						       dev->name,rsst);
						scb_wrcbl(dev, lp->tx_link);
						scb_command(dev, SCB_CUstart);
						outb(0,ioaddr+SIGNAL_CA);
					}
				}
				netif_wake_queue(dev);
			}
			else
			{
				unsigned short status = scb_status(dev);
				if (SCB_CUdead(status))
				{
					unsigned short txstatus = eexp_hw_lasttxstat(dev);
					printk(KERN_WARNING "%s: Transmit timed out, CU not active status %04x %04x, restarting...\n",
					       dev->name, status, txstatus);
					eexp_hw_txrestart(dev);
				}
				else
				{
					unsigned short txstatus = eexp_hw_lasttxstat(dev);
					if (netif_queue_stopped(dev) && !txstatus)
					{
						printk(KERN_WARNING "%s: CU wedged, status %04x %04x, resetting...\n",
						       dev->name,status,txstatus);
						eexp_hw_init586(dev);
						netif_wake_queue(dev);
					}
					else
					{
						printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
					}
				}
			}
		}
	}
	else
	{
		if (time_after(jiffies, lp->init_time + 10))
		{
			unsigned short status = scb_status(dev);
			printk(KERN_WARNING "%s: i82586 startup timed out, status %04x, resetting...\n",
			       dev->name, status);
			eexp_hw_init586(dev);
			netif_wake_queue(dev);
		}
	}
}

static void eexp_timeout(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
#ifdef CONFIG_SMP
	unsigned long flags;
#endif
	int status;

	disable_irq(dev->irq);

	/*
	 *	Best would be to use synchronize_irq(); spin_lock() here
	 *	lets make it work first..
	 */

#ifdef CONFIG_SMP
	spin_lock_irqsave(&lp->lock, flags);
#endif

	status = scb_status(dev);
	unstick_cu(dev);
	printk(KERN_INFO "%s: transmit timed out, %s?\n", dev->name,
	       (SCB_complete(status)?"lost interrupt":
		"board on fire"));
	dev->stats.tx_errors++;
	lp->last_tx = jiffies;
	if (!SCB_complete(status)) {
		scb_command(dev, SCB_CUabort);
		outb(0,dev->base_addr+SIGNAL_CA);
	}
	netif_wake_queue(dev);
#ifdef CONFIG_SMP
	spin_unlock_irqrestore(&lp->lock, flags);
#endif
}

/*
 * Called to transmit a packet, or to allow us to right ourselves
 * if the kernel thinks we've died.
 */
static int eexp_xmit(struct sk_buff *buf, struct net_device *dev)
{
	short length = buf->len;
#ifdef CONFIG_SMP
	struct net_local *lp = netdev_priv(dev);
	unsigned long flags;
#endif

#if NET_DEBUG > 6
	printk(KERN_DEBUG "%s: eexp_xmit()\n", dev->name);
#endif

	if (buf->len < ETH_ZLEN) {
		if (skb_padto(buf, ETH_ZLEN))
			return 0;
		length = ETH_ZLEN;
	}

	disable_irq(dev->irq);

	/*
	 *	Best would be to use synchronize_irq(); spin_lock() here
	 *	lets make it work first..
	 */

#ifdef CONFIG_SMP
	spin_lock_irqsave(&lp->lock, flags);
#endif

	{
		unsigned short *data = (unsigned short *)buf->data;

		dev->stats.tx_bytes += length;

	        eexp_hw_tx_pio(dev,data,length);
	}
	dev_kfree_skb(buf);
#ifdef CONFIG_SMP
	spin_unlock_irqrestore(&lp->lock, flags);
#endif
	enable_irq(dev->irq);
	return 0;
}

/*
 * Handle an EtherExpress interrupt
 * If we've finished initializing, start the RU and CU up.
 * If we've already started, reap tx buffers, handle any received packets,
 * check to make sure we've not become wedged.
 */

static unsigned short eexp_start_irq(struct net_device *dev,
				     unsigned short status)
{
	unsigned short ack_cmd = SCB_ack(status);
	struct net_local *lp = netdev_priv(dev);
	unsigned short ioaddr = dev->base_addr;
	if ((dev->flags & IFF_UP) && !(lp->started & STARTED_CU)) {
		short diag_status, tdr_status;
		while (SCB_CUstat(status)==2)
			status = scb_status(dev);
#if NET_DEBUG > 4
		printk("%s: CU went non-active (status %04x)\n",
		       dev->name, status);
#endif

		outw(CONF_DIAG_RESULT & ~31, ioaddr + SM_PTR);
		diag_status = inw(ioaddr + SHADOW(CONF_DIAG_RESULT));
		if (diag_status & 1<<11) {
			printk(KERN_WARNING "%s: 82586 failed self-test\n",
			       dev->name);
		} else if (!(diag_status & 1<<13)) {
			printk(KERN_WARNING "%s: 82586 self-test failed to complete\n", dev->name);
		}

		outw(CONF_TDR_RESULT & ~31, ioaddr + SM_PTR);
		tdr_status = inw(ioaddr + SHADOW(CONF_TDR_RESULT));
		if (tdr_status & (TDR_SHORT|TDR_OPEN)) {
			printk(KERN_WARNING "%s: TDR reports cable %s at %d tick%s\n", dev->name, (tdr_status & TDR_SHORT)?"short":"broken", tdr_status & TDR_TIME, ((tdr_status & TDR_TIME) != 1) ? "s" : "");
		}
		else if (tdr_status & TDR_XCVRPROBLEM) {
			printk(KERN_WARNING "%s: TDR reports transceiver problem\n", dev->name);
		}
		else if (tdr_status & TDR_LINKOK) {
#if NET_DEBUG > 4
			printk(KERN_DEBUG "%s: TDR reports link OK\n", dev->name);
#endif
		} else {
			printk("%s: TDR is ga-ga (status %04x)\n", dev->name,
			       tdr_status);
		}

		lp->started |= STARTED_CU;
		scb_wrcbl(dev, lp->tx_link);
		/* if the RU isn't running, start it now */
		if (!(lp->started & STARTED_RU)) {
			ack_cmd |= SCB_RUstart;
			scb_wrrfa(dev, lp->rx_buf_start);
			lp->rx_ptr = lp->rx_buf_start;
			lp->started |= STARTED_RU;
		}
		ack_cmd |= SCB_CUstart | 0x2000;
	}

	if ((dev->flags & IFF_UP) && !(lp->started & STARTED_RU) && SCB_RUstat(status)==4)
		lp->started|=STARTED_RU;

	return ack_cmd;
}

static void eexp_cmd_clear(struct net_device *dev)
{
	unsigned long int oldtime = jiffies;
	while (scb_rdcmd(dev) && (time_before(jiffies, oldtime + 10)));
	if (scb_rdcmd(dev)) {
		printk("%s: command didn't clear\n", dev->name);
	}
}

static irqreturn_t eexp_irq(int dummy, void *dev_info)
{
	struct net_device *dev = dev_info;
	struct net_local *lp;
	unsigned short ioaddr,status,ack_cmd;
	unsigned short old_read_ptr, old_write_ptr;

	lp = netdev_priv(dev);
	ioaddr = dev->base_addr;

	spin_lock(&lp->lock);

	old_read_ptr = inw(ioaddr+READ_PTR);
	old_write_ptr = inw(ioaddr+WRITE_PTR);

	outb(SIRQ_dis|irqrmap[dev->irq], ioaddr+SET_IRQ);

	status = scb_status(dev);

#if NET_DEBUG > 4
	printk(KERN_DEBUG "%s: interrupt (status %x)\n", dev->name, status);
#endif

	if (lp->started == (STARTED_CU | STARTED_RU)) {

		do {
			eexp_cmd_clear(dev);

			ack_cmd = SCB_ack(status);
			scb_command(dev, ack_cmd);
			outb(0,ioaddr+SIGNAL_CA);

			eexp_cmd_clear(dev);

			if (SCB_complete(status)) {
				if (!eexp_hw_lasttxstat(dev)) {
					printk("%s: tx interrupt but no status\n", dev->name);
				}
			}

			if (SCB_rxdframe(status))
				eexp_hw_rx_pio(dev);

			status = scb_status(dev);
		} while (status & 0xc000);

		if (SCB_RUdead(status))
		{
			printk(KERN_WARNING "%s: RU stopped: status %04x\n",
			       dev->name,status);
#if 0
			printk(KERN_WARNING "%s: cur_rfd=%04x, cur_rbd=%04x\n", dev->name, lp->cur_rfd, lp->cur_rbd);
			outw(lp->cur_rfd, ioaddr+READ_PTR);
			printk(KERN_WARNING "%s: [%04x]\n", dev->name, inw(ioaddr+DATAPORT));
			outw(lp->cur_rfd+6, ioaddr+READ_PTR);
			printk(KERN_WARNING "%s: rbd is %04x\n", dev->name, rbd= inw(ioaddr+DATAPORT));
			outw(rbd, ioaddr+READ_PTR);
			printk(KERN_WARNING "%s: [%04x %04x] ", dev->name, inw(ioaddr+DATAPORT), inw(ioaddr+DATAPORT));
			outw(rbd+8, ioaddr+READ_PTR);
			printk("[%04x]\n", inw(ioaddr+DATAPORT));
#endif
			dev->stats.rx_errors++;
#if 1
		        eexp_hw_rxinit(dev);
#else
			lp->cur_rfd = lp->first_rfd;
#endif
			scb_wrrfa(dev, lp->rx_buf_start);
			scb_command(dev, SCB_RUstart);
			outb(0,ioaddr+SIGNAL_CA);
		}
	} else {
		if (status & 0x8000)
			ack_cmd = eexp_start_irq(dev, status);
		else
			ack_cmd = SCB_ack(status);
		scb_command(dev, ack_cmd);
		outb(0,ioaddr+SIGNAL_CA);
	}

	eexp_cmd_clear(dev);

	outb(SIRQ_en|irqrmap[dev->irq], ioaddr+SET_IRQ);

#if NET_DEBUG > 6
	printk("%s: leaving eexp_irq()\n", dev->name);
#endif
	outw(old_read_ptr, ioaddr+READ_PTR);
	outw(old_write_ptr, ioaddr+WRITE_PTR);

	spin_unlock(&lp->lock);
	return IRQ_HANDLED;
}

/*
 * Hardware access functions
 */

/*
 * Set the cable type to use.
 */

static void eexp_hw_set_interface(struct net_device *dev)
{
	unsigned char oldval = inb(dev->base_addr + 0x300e);
	oldval &= ~0x82;
	switch (dev->if_port) {
	case TPE:
		oldval |= 0x2;
	case BNC:
		oldval |= 0x80;
		break;
	}
	outb(oldval, dev->base_addr+0x300e);
	mdelay(20);
}

/*
 * Check all the receive buffers, and hand any received packets
 * to the upper levels. Basic sanity check on each frame
 * descriptor, though we don't bother trying to fix broken ones.
 */

static void eexp_hw_rx_pio(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned short rx_block = lp->rx_ptr;
	unsigned short boguscount = lp->num_rx_bufs;
	unsigned short ioaddr = dev->base_addr;
	unsigned short status;

#if NET_DEBUG > 6
	printk(KERN_DEBUG "%s: eexp_hw_rx()\n", dev->name);
#endif

 	do {
 		unsigned short rfd_cmd, rx_next, pbuf, pkt_len;

		outw(rx_block, ioaddr + READ_PTR);
		status = inw(ioaddr + DATAPORT);

		if (FD_Done(status))
		{
			rfd_cmd = inw(ioaddr + DATAPORT);
			rx_next = inw(ioaddr + DATAPORT);
			pbuf = inw(ioaddr + DATAPORT);

			outw(pbuf, ioaddr + READ_PTR);
			pkt_len = inw(ioaddr + DATAPORT);

			if (rfd_cmd!=0x0000)
  			{
				printk(KERN_WARNING "%s: rfd_cmd not zero:0x%04x\n",
				       dev->name, rfd_cmd);
				continue;
			}
			else if (pbuf!=rx_block+0x16)
			{
				printk(KERN_WARNING "%s: rfd and rbd out of sync 0x%04x 0x%04x\n",
				       dev->name, rx_block+0x16, pbuf);
				continue;
			}
			else if ((pkt_len & 0xc000)!=0xc000)
			{
				printk(KERN_WARNING "%s: EOF or F not set on received buffer (%04x)\n",
				       dev->name, pkt_len & 0xc000);
  				continue;
  			}
  			else if (!FD_OK(status))
			{
				dev->stats.rx_errors++;
				if (FD_CRC(status))
					dev->stats.rx_crc_errors++;
				if (FD_Align(status))
					dev->stats.rx_frame_errors++;
				if (FD_Resrc(status))
					dev->stats.rx_fifo_errors++;
				if (FD_DMA(status))
					dev->stats.rx_over_errors++;
				if (FD_Short(status))
					dev->stats.rx_length_errors++;
			}
			else
			{
				struct sk_buff *skb;
				pkt_len &= 0x3fff;
				skb = dev_alloc_skb(pkt_len+16);
				if (skb == NULL)
				{
					printk(KERN_WARNING "%s: Memory squeeze, dropping packet\n",dev->name);
					dev->stats.rx_dropped++;
					break;
				}
				skb_reserve(skb, 2);
				outw(pbuf+10, ioaddr+READ_PTR);
			        insw(ioaddr+DATAPORT, skb_put(skb,pkt_len),(pkt_len+1)>>1);
				skb->protocol = eth_type_trans(skb,dev);
				netif_rx(skb);
				dev->last_rx = jiffies;
				dev->stats.rx_packets++;
				dev->stats.rx_bytes += pkt_len;
			}
			outw(rx_block, ioaddr+WRITE_PTR);
			outw(0, ioaddr+DATAPORT);
			outw(0, ioaddr+DATAPORT);
			rx_block = rx_next;
		}
	} while (FD_Done(status) && boguscount--);
	lp->rx_ptr = rx_block;
}

/*
 * Hand a packet to the card for transmission
 * If we get here, we MUST have already checked
 * to make sure there is room in the transmit
 * buffer region.
 */

static void eexp_hw_tx_pio(struct net_device *dev, unsigned short *buf,
		       unsigned short len)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned short ioaddr = dev->base_addr;

	if (LOCKUP16 || lp->width) {
		/* Stop the CU so that there is no chance that it
		   jumps off to a bogus address while we are writing the
		   pointer to the next transmit packet in 8-bit mode --
		   this eliminates the "CU wedged" errors in 8-bit mode.
		   (Zoltan Szilagyi 10-12-96) */
		scb_command(dev, SCB_CUsuspend);
		outw(0xFFFF, ioaddr+SIGNAL_CA);
	}

 	outw(lp->tx_head, ioaddr + WRITE_PTR);

	outw(0x0000, ioaddr + DATAPORT);
        outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
	outw(lp->tx_head+0x08, ioaddr + DATAPORT);
	outw(lp->tx_head+0x0e, ioaddr + DATAPORT);

	outw(0x0000, ioaddr + DATAPORT);
	outw(0x0000, ioaddr + DATAPORT);
	outw(lp->tx_head+0x08, ioaddr + DATAPORT);

	outw(0x8000|len, ioaddr + DATAPORT);
	outw(-1, ioaddr + DATAPORT);
	outw(lp->tx_head+0x16, ioaddr + DATAPORT);
	outw(0, ioaddr + DATAPORT);

        outsw(ioaddr + DATAPORT, buf, (len+1)>>1);

	outw(lp->tx_tail+0xc, ioaddr + WRITE_PTR);
	outw(lp->tx_head, ioaddr + DATAPORT);

	dev->trans_start = jiffies;
	lp->tx_tail = lp->tx_head;
	if (lp->tx_head==TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
		lp->tx_head = TX_BUF_START;
	else
		lp->tx_head += TX_BUF_SIZE;
	if (lp->tx_head != lp->tx_reap)
		netif_wake_queue(dev);

	if (LOCKUP16 || lp->width) {
		/* Restart the CU so that the packet can actually
		   be transmitted. (Zoltan Szilagyi 10-12-96) */
		scb_command(dev, SCB_CUresume);
		outw(0xFFFF, ioaddr+SIGNAL_CA);
	}

	dev->stats.tx_packets++;
	lp->last_tx = jiffies;
}

/*
 * Sanity check the suspected EtherExpress card
 * Read hardware address, reset card, size memory and initialize buffer
 * memory pointers. These are held in dev->priv, in case someone has more
 * than one card in a machine.
 */

static int __init eexp_hw_probe(struct net_device *dev, unsigned short ioaddr)
{
	unsigned short hw_addr[3];
	unsigned char buswidth;
	unsigned int memory_size;
	int i;
	unsigned short xsum = 0;
	struct net_local *lp = netdev_priv(dev);

	printk("%s: EtherExpress 16 at %#x ",dev->name,ioaddr);

	outb(ASIC_RST, ioaddr+EEPROM_Ctrl);
	outb(0, ioaddr+EEPROM_Ctrl);
	udelay(500);
	outb(i586_RST, ioaddr+EEPROM_Ctrl);

	hw_addr[0] = eexp_hw_readeeprom(ioaddr,2);
	hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
	hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);

	/* Standard Address or Compaq LTE Address */
	if (!((hw_addr[2]==0x00aa && ((hw_addr[1] & 0xff00)==0x0000)) ||
	      (hw_addr[2]==0x0080 && ((hw_addr[1] & 0xff00)==0x5F00))))
	{
		printk(" rejected: invalid address %04x%04x%04x\n",
			hw_addr[2],hw_addr[1],hw_addr[0]);
		return -ENODEV;
	}

	/* Calculate the EEPROM checksum.  Carry on anyway if it's bad,
	 * though.
	 */
	for (i = 0; i < 64; i++)
		xsum += eexp_hw_readeeprom(ioaddr, i);
	if (xsum != 0xbaba)
		printk(" (bad EEPROM xsum 0x%02x)", xsum);

	dev->base_addr = ioaddr;
	for ( i=0 ; i<6 ; i++ )
		dev->dev_addr[i] = ((unsigned char *)hw_addr)[5-i];

	{
		static char irqmap[]={0, 9, 3, 4, 5, 10, 11, 0};
		unsigned short setupval = eexp_hw_readeeprom(ioaddr,0);

		/* Use the IRQ from EEPROM if none was given */
		if (!dev->irq)
			dev->irq = irqmap[setupval>>13];

		if (dev->if_port == 0xff) {
			dev->if_port = !(setupval & 0x1000) ? AUI :
				eexp_hw_readeeprom(ioaddr,5) & 0x1 ? TPE : BNC;
		}

		buswidth = !((setupval & 0x400) >> 10);
	}

	memset(lp, 0, sizeof(struct net_local));
	spin_lock_init(&lp->lock);

 	printk("(IRQ %d, %s connector, %d-bit bus", dev->irq,
 	       eexp_ifmap[dev->if_port], buswidth?8:16);

	if (!request_region(dev->base_addr + 0x300e, 1, "EtherExpress"))
		return -EBUSY;

 	eexp_hw_set_interface(dev);

	release_region(dev->base_addr + 0x300e, 1);

	/* Find out how much RAM we have on the card */
	outw(0, dev->base_addr + WRITE_PTR);
	for (i = 0; i < 32768; i++)
		outw(0, dev->base_addr + DATAPORT);

        for (memory_size = 0; memory_size < 64; memory_size++)
	{
		outw(memory_size<<10, dev->base_addr + READ_PTR);
		if (inw(dev->base_addr+DATAPORT))
			break;
		outw(memory_size<<10, dev->base_addr + WRITE_PTR);
		outw(memory_size | 0x5000, dev->base_addr+DATAPORT);
		outw(memory_size<<10, dev->base_addr + READ_PTR);
		if (inw(dev->base_addr+DATAPORT) != (memory_size | 0x5000))
			break;
	}

	/* Sort out the number of buffers.  We may have 16, 32, 48 or 64k
	 * of RAM to play with.
	 */
	lp->num_tx_bufs = 4;
	lp->rx_buf_end = 0x3ff6;
	switch (memory_size)
	{
	case 64:
		lp->rx_buf_end += 0x4000;
	case 48:
		lp->num_tx_bufs += 4;
		lp->rx_buf_end += 0x4000;
	case 32:
		lp->rx_buf_end += 0x4000;
	case 16:
		printk(", %dk RAM)\n", memory_size);
		break;
	default:
		printk(") bad memory size (%dk).\n", memory_size);
		return -ENODEV;
		break;
	}

	lp->rx_buf_start = TX_BUF_START + (lp->num_tx_bufs*TX_BUF_SIZE);
	lp->width = buswidth;

	dev->open = eexp_open;
	dev->stop = eexp_close;
	dev->hard_start_xmit = eexp_xmit;
	dev->set_multicast_list = &eexp_set_multicast;
	dev->tx_timeout = eexp_timeout;
	dev->watchdog_timeo = 2*HZ;

	return register_netdev(dev);
}

/*
 * Read a word from the EtherExpress on-board serial EEPROM.
 * The EEPROM contains 64 words of 16 bits.
 */
static unsigned short __init eexp_hw_readeeprom(unsigned short ioaddr,
						    unsigned char location)
{
	unsigned short cmd = 0x180|(location&0x7f);
	unsigned short rval = 0,wval = EC_CS|i586_RST;
	int i;

	outb(EC_CS|i586_RST,ioaddr+EEPROM_Ctrl);
	for (i=0x100 ; i ; i>>=1 )
	{
		if (cmd&i)
			wval |= EC_Wr;
		else
			wval &= ~EC_Wr;

		outb(wval,ioaddr+EEPROM_Ctrl);
		outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
		eeprom_delay();
		outb(wval,ioaddr+EEPROM_Ctrl);
		eeprom_delay();
	}
	wval &= ~EC_Wr;
	outb(wval,ioaddr+EEPROM_Ctrl);
	for (i=0x8000 ; i ; i>>=1 )
	{
		outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
		eeprom_delay();
		if (inb(ioaddr+EEPROM_Ctrl)&EC_Rd)
			rval |= i;
		outb(wval,ioaddr+EEPROM_Ctrl);
		eeprom_delay();
	}
	wval &= ~EC_CS;
	outb(wval|EC_Clk,ioaddr+EEPROM_Ctrl);
	eeprom_delay();
	outb(wval,ioaddr+EEPROM_Ctrl);
	eeprom_delay();
	return rval;
}

/*
 * Reap tx buffers and return last transmit status.
 * if ==0 then either:
 *    a) we're not transmitting anything, so why are we here?
 *    b) we've died.
 * otherwise, Stat_Busy(return) means we've still got some packets
 * to transmit, Stat_Done(return) means our buffers should be empty
 * again
 */

static unsigned short eexp_hw_lasttxstat(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned short tx_block = lp->tx_reap;
	unsigned short status;

	if (!netif_queue_stopped(dev) && lp->tx_head==lp->tx_reap)
		return 0x0000;

	do
	{
		outw(tx_block & ~31, dev->base_addr + SM_PTR);
		status = inw(dev->base_addr + SHADOW(tx_block));
		if (!Stat_Done(status))
		{
			lp->tx_link = tx_block;
			return status;
		}
		else
		{
			lp->last_tx_restart = 0;
			dev->stats.collisions += Stat_NoColl(status);
			if (!Stat_OK(status))
			{
				char *whatsup = NULL;
				dev->stats.tx_errors++;
  				if (Stat_Abort(status))
					dev->stats.tx_aborted_errors++;
				if (Stat_TNoCar(status)) {
					whatsup = "aborted, no carrier";
					dev->stats.tx_carrier_errors++;
				}
				if (Stat_TNoCTS(status)) {
					whatsup = "aborted, lost CTS";
					dev->stats.tx_carrier_errors++;
				}
				if (Stat_TNoDMA(status)) {
					whatsup = "FIFO underran";
					dev->stats.tx_fifo_errors++;
				}
				if (Stat_TXColl(status)) {
					whatsup = "aborted, too many collisions";
					dev->stats.tx_aborted_errors++;
				}
				if (whatsup)
					printk(KERN_INFO "%s: transmit %s\n",
					       dev->name, whatsup);
			}
			else
				dev->stats.tx_packets++;
		}
		if (tx_block == TX_BUF_START+((lp->num_tx_bufs-1)*TX_BUF_SIZE))
			lp->tx_reap = tx_block = TX_BUF_START;
		else
			lp->tx_reap = tx_block += TX_BUF_SIZE;
		netif_wake_queue(dev);
	}
	while (lp->tx_reap != lp->tx_head);

	lp->tx_link = lp->tx_tail + 0x08;

	return status;
}

/*
 * This should never happen. It is called when some higher routine detects
 * that the CU has stopped, to try to restart it from the last packet we knew
 * we were working on, or the idle loop if we had finished for the time.
 */

static void eexp_hw_txrestart(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned short ioaddr = dev->base_addr;

	lp->last_tx_restart = lp->tx_link;
	scb_wrcbl(dev, lp->tx_link);
	scb_command(dev, SCB_CUstart);
	outb(0,ioaddr+SIGNAL_CA);

	{
		unsigned short boguscount=50,failcount=5;
		while (!scb_status(dev))
		{
			if (!--boguscount)
			{
				if (--failcount)
				{
					printk(KERN_WARNING "%s: CU start timed out, status %04x, cmd %04x\n", dev->name, scb_status(dev), scb_rdcmd(dev));
				        scb_wrcbl(dev, lp->tx_link);
					scb_command(dev, SCB_CUstart);
					outb(0,ioaddr+SIGNAL_CA);
					boguscount = 100;
				}
				else
				{
					printk(KERN_WARNING "%s: Failed to restart CU, resetting board...\n",dev->name);
					eexp_hw_init586(dev);
					netif_wake_queue(dev);
					return;
				}
			}
		}
	}
}

/*
 * Writes down the list of transmit buffers into card memory.  Each
 * entry consists of an 82586 transmit command, followed by a jump
 * pointing to itself.  When we want to transmit a packet, we write
 * the data into the appropriate transmit buffer and then modify the
 * preceding jump to point at the new transmit command.  This means that
 * the 586 command unit is continuously active.
 */

static void eexp_hw_txinit(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned short tx_block = TX_BUF_START;
	unsigned short curtbuf;
	unsigned short ioaddr = dev->base_addr;

	for ( curtbuf=0 ; curtbuf<lp->num_tx_bufs ; curtbuf++ )
	{
		outw(tx_block, ioaddr + WRITE_PTR);

	        outw(0x0000, ioaddr + DATAPORT);
		outw(Cmd_INT|Cmd_Xmit, ioaddr + DATAPORT);
		outw(tx_block+0x08, ioaddr + DATAPORT);
		outw(tx_block+0x0e, ioaddr + DATAPORT);

		outw(0x0000, ioaddr + DATAPORT);
		outw(0x0000, ioaddr + DATAPORT);
		outw(tx_block+0x08, ioaddr + DATAPORT);

		outw(0x8000, ioaddr + DATAPORT);
		outw(-1, ioaddr + DATAPORT);
		outw(tx_block+0x16, ioaddr + DATAPORT);
		outw(0x0000, ioaddr + DATAPORT);

		tx_block += TX_BUF_SIZE;
	}
	lp->tx_head = TX_BUF_START;
	lp->tx_reap = TX_BUF_START;
	lp->tx_tail = tx_block - TX_BUF_SIZE;
	lp->tx_link = lp->tx_tail + 0x08;
	lp->rx_buf_start = tx_block;

}

/*
 * Write the circular list of receive buffer descriptors to card memory.
 * The end of the list isn't marked, which means that the 82586 receive
 * unit will loop until buffers become available (this avoids it giving us
 * "out of resources" messages).
 */

static void eexp_hw_rxinit(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned short rx_block = lp->rx_buf_start;
	unsigned short ioaddr = dev->base_addr;

	lp->num_rx_bufs = 0;
	lp->rx_first = lp->rx_ptr = rx_block;
	do
	{
		lp->num_rx_bufs++;

		outw(rx_block, ioaddr + WRITE_PTR);

		outw(0, ioaddr + DATAPORT);  outw(0, ioaddr+DATAPORT);
		outw(rx_block + RX_BUF_SIZE, ioaddr+DATAPORT);
		outw(0xffff, ioaddr+DATAPORT);

		outw(0x0000, ioaddr+DATAPORT);
		outw(0xdead, ioaddr+DATAPORT);
		outw(0xdead, ioaddr+DATAPORT);
		outw(0xdead, ioaddr+DATAPORT);
		outw(0xdead, ioaddr+DATAPORT);
		outw(0xdead, ioaddr+DATAPORT);
		outw(0xdead, ioaddr+DATAPORT);

		outw(0x0000, ioaddr+DATAPORT);
		outw(rx_block + RX_BUF_SIZE + 0x16, ioaddr+DATAPORT);
		outw(rx_block + 0x20, ioaddr+DATAPORT);
		outw(0, ioaddr+DATAPORT);
		outw(RX_BUF_SIZE-0x20, ioaddr+DATAPORT);

		lp->rx_last = rx_block;
		rx_block += RX_BUF_SIZE;
	} while (rx_block <= lp->rx_buf_end-RX_BUF_SIZE);


	/* Make first Rx frame descriptor point to first Rx buffer
           descriptor */
	outw(lp->rx_first + 6, ioaddr+WRITE_PTR);
	outw(lp->rx_first + 0x16, ioaddr+DATAPORT);

	/* Close Rx frame descriptor ring */
  	outw(lp->rx_last + 4, ioaddr+WRITE_PTR);
  	outw(lp->rx_first, ioaddr+DATAPORT);

	/* Close Rx buffer descriptor ring */
	outw(lp->rx_last + 0x16 + 2, ioaddr+WRITE_PTR);
	outw(lp->rx_first + 0x16, ioaddr+DATAPORT);

}

/*
 * Un-reset the 586, and start the configuration sequence. We don't wait for
 * this to finish, but allow the interrupt handler to start the CU and RU for
 * us.  We can't start the receive/transmission system up before we know that
 * the hardware is configured correctly.
 */

static void eexp_hw_init586(struct net_device *dev)
{
	struct net_local *lp = netdev_priv(dev);
	unsigned short ioaddr = dev->base_addr;
	int i;

#if NET_DEBUG > 6
	printk("%s: eexp_hw_init586()\n", dev->name);
#endif

	lp->started = 0;

	set_loopback(dev);

	outb(SIRQ_dis|irqrmap[dev->irq],ioaddr+SET_IRQ);

	/* Download the startup code */
	outw(lp->rx_buf_end & ~31, ioaddr + SM_PTR);
	outw(lp->width?0x0001:0x0000, ioaddr + 0x8006);
	outw(0x0000, ioaddr + 0x8008);
	outw(0x0000, ioaddr + 0x800a);
	outw(0x0000, ioaddr + 0x800c);
	outw(0x0000, ioaddr + 0x800e);

	for (i = 0; i < (sizeof(start_code)); i+=32) {
		int j;
		outw(i, ioaddr + SM_PTR);
		for (j = 0; j < 16; j+=2)
			outw(start_code[(i+j)/2],
			     ioaddr+0x4000+j);
		for (j = 0; j < 16; j+=2)
			outw(start_code[(i+j+16)/2],
			     ioaddr+0x8000+j);
	}

	/* Do we want promiscuous mode or multicast? */
	outw(CONF_PROMISC & ~31, ioaddr+SM_PTR);
	i = inw(ioaddr+SHADOW(CONF_PROMISC));
	outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1),
	     ioaddr+SHADOW(CONF_PROMISC));
	lp->was_promisc = dev->flags & IFF_PROMISC;
#if 0
	eexp_setup_filter(dev);
#endif

	/* Write our hardware address */
	outw(CONF_HWADDR & ~31, ioaddr+SM_PTR);
	outw(((unsigned short *)dev->dev_addr)[0], ioaddr+SHADOW(CONF_HWADDR));
	outw(((unsigned short *)dev->dev_addr)[1],
	     ioaddr+SHADOW(CONF_HWADDR+2));
	outw(((unsigned short *)dev->dev_addr)[2],
	     ioaddr+SHADOW(CONF_HWADDR+4));

	eexp_hw_txinit(dev);
	eexp_hw_rxinit(dev);

	outb(0,ioaddr+EEPROM_Ctrl);
	mdelay(5);

	scb_command(dev, 0xf000);
	outb(0,ioaddr+SIGNAL_CA);

	outw(0, ioaddr+SM_PTR);

	{
		unsigned short rboguscount=50,rfailcount=5;
		while (inw(ioaddr+0x4000))
		{
			if (!--rboguscount)
			{
				printk(KERN_WARNING "%s: i82586 reset timed out, kicking...\n",
					dev->name);
				scb_command(dev, 0);
				outb(0,ioaddr+SIGNAL_CA);
				rboguscount = 100;
				if (!--rfailcount)
				{
					printk(KERN_WARNING "%s: i82586 not responding, giving up.\n",
						dev->name);
					return;
				}
			}
		}
	}

        scb_wrcbl(dev, CONF_LINK);
	scb_command(dev, 0xf000|SCB_CUstart);
	outb(0,ioaddr+SIGNAL_CA);

	{
		unsigned short iboguscount=50,ifailcount=5;
		while (!scb_status(dev))
		{
			if (!--iboguscount)
			{
				if (--ifailcount)
				{
					printk(KERN_WARNING "%s: i82586 initialization timed out, status %04x, cmd %04x\n",
						dev->name, scb_status(dev), scb_rdcmd(dev));
					scb_wrcbl(dev, CONF_LINK);
				        scb_command(dev, 0xf000|SCB_CUstart);
					outb(0,ioaddr+SIGNAL_CA);
					iboguscount = 100;
				}
				else
				{
					printk(KERN_WARNING "%s: Failed to initialize i82586, giving up.\n",dev->name);
					return;
				}
			}
		}
	}

	clear_loopback(dev);
	outb(SIRQ_en|irqrmap[dev->irq],ioaddr+SET_IRQ);

	lp->init_time = jiffies;
#if NET_DEBUG > 6
        printk("%s: leaving eexp_hw_init586()\n", dev->name);
#endif
	return;
}

static void eexp_setup_filter(struct net_device *dev)
{
	struct dev_mc_list *dmi = dev->mc_list;
	unsigned short ioaddr = dev->base_addr;
	int count = dev->mc_count;
	int i;
	if (count > 8) {
		printk(KERN_INFO "%s: too many multicast addresses (%d)\n",
		       dev->name, count);
		count = 8;
	}

	outw(CONF_NR_MULTICAST & ~31, ioaddr+SM_PTR);
	outw(count, ioaddr+SHADOW(CONF_NR_MULTICAST));
	for (i = 0; i < count; i++) {
		unsigned short *data = (unsigned short *)dmi->dmi_addr;
		if (!dmi) {
			printk(KERN_INFO "%s: too few multicast addresses\n", dev->name);
			break;
		}
		if (dmi->dmi_addrlen != ETH_ALEN) {
			printk(KERN_INFO "%s: invalid multicast address length given.\n", dev->name);
			continue;
		}
		outw((CONF_MULTICAST+(6*i)) & ~31, ioaddr+SM_PTR);
		outw(data[0], ioaddr+SHADOW(CONF_MULTICAST+(6*i)));
		outw((CONF_MULTICAST+(6*i)+2) & ~31, ioaddr+SM_PTR);
		outw(data[1], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+2));
		outw((CONF_MULTICAST+(6*i)+4) & ~31, ioaddr+SM_PTR);
		outw(data[2], ioaddr+SHADOW(CONF_MULTICAST+(6*i)+4));
	}
}

/*
 * Set or clear the multicast filter for this adaptor.
 */
static void
eexp_set_multicast(struct net_device *dev)
{
        unsigned short ioaddr = dev->base_addr;
        struct net_local *lp = netdev_priv(dev);
        int kick = 0, i;
        if ((dev->flags & IFF_PROMISC) != lp->was_promisc) {
                outw(CONF_PROMISC & ~31, ioaddr+SM_PTR);
                i = inw(ioaddr+SHADOW(CONF_PROMISC));
                outw((dev->flags & IFF_PROMISC)?(i|1):(i & ~1),
                     ioaddr+SHADOW(CONF_PROMISC));
                lp->was_promisc = dev->flags & IFF_PROMISC;
                kick = 1;
        }
        if (!(dev->flags & IFF_PROMISC)) {
                eexp_setup_filter(dev);
                if (lp->old_mc_count != dev->mc_count) {
                        kick = 1;
                        lp->old_mc_count = dev->mc_count;
                }
        }
        if (kick) {
                unsigned long oj;
                scb_command(dev, SCB_CUsuspend);
                outb(0, ioaddr+SIGNAL_CA);
                outb(0, ioaddr+SIGNAL_CA);
#if 0
                printk("%s: waiting for CU to go suspended\n", dev->name);
#endif
                oj = jiffies;
                while ((SCB_CUstat(scb_status(dev)) == 2) &&
                       (time_before(jiffies, oj + 2000)));
		if (SCB_CUstat(scb_status(dev)) == 2)
			printk("%s: warning, CU didn't stop\n", dev->name);
                lp->started &= ~(STARTED_CU);
                scb_wrcbl(dev, CONF_LINK);
                scb_command(dev, SCB_CUstart);
                outb(0, ioaddr+SIGNAL_CA);
        }
}


/*
 * MODULE stuff
 */

#ifdef MODULE

#define EEXP_MAX_CARDS     4    /* max number of cards to support */

static struct net_device *dev_eexp[EEXP_MAX_CARDS];
static int irq[EEXP_MAX_CARDS];
static int io[EEXP_MAX_CARDS];

module_param_array(io, int, NULL, 0);
module_param_array(irq, int, NULL, 0);
MODULE_PARM_DESC(io, "EtherExpress 16 I/O base address(es)");
MODULE_PARM_DESC(irq, "EtherExpress 16 IRQ number(s)");
MODULE_LICENSE("GPL");


/* Ideally the user would give us io=, irq= for every card.  If any parameters
 * are specified, we verify and then use them.  If no parameters are given, we
 * autoprobe for one card only.
 */
int __init init_module(void)
{
	struct net_device *dev;
	int this_dev, found = 0;

	for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
		dev = alloc_etherdev(sizeof(struct net_local));
		dev->irq = irq[this_dev];
		dev->base_addr = io[this_dev];
		if (io[this_dev] == 0) {
			if (this_dev)
				break;
			printk(KERN_NOTICE "eexpress.c: Module autoprobe not recommended, give io=xx.\n");
		}
		if (do_express_probe(dev) == 0) {
			dev_eexp[this_dev] = dev;
			found++;
			continue;
		}
		printk(KERN_WARNING "eexpress.c: Failed to register card at 0x%x.\n", io[this_dev]);
		free_netdev(dev);
		break;
	}
	if (found)
		return 0;
	return -ENXIO;
}

void __exit cleanup_module(void)
{
	int this_dev;

	for (this_dev = 0; this_dev < EEXP_MAX_CARDS; this_dev++) {
		struct net_device *dev = dev_eexp[this_dev];
		if (dev) {
			unregister_netdev(dev);
			free_netdev(dev);
		}
	}
}
#endif

/*
 * Local Variables:
 *  c-file-style: "linux"
 *  tab-width: 8
 * End:
 */
