/* 3c527.c: 3Com Etherlink/MC32 driver for Linux 2.4 and 2.6.
 *
 *	(c) Copyright 1998 Red Hat Software Inc
 *	Written by Alan Cox.
 *	Further debugging by Carl Drougge.
 *      Initial SMP support by Felipe W Damasio <felipewd@terra.com.br>
 *      Heavily modified by Richard Procter <rnp@paradise.net.nz>
 *
 *	Based on skeleton.c written 1993-94 by Donald Becker and ne2.c
 *	(for the MCA stuff) written by Wim Dumon.
 *
 *	Thanks to 3Com for making this possible by providing me with the
 *	documentation.
 *
 *	This software may be used and distributed according to the terms
 *	of the GNU General Public License, incorporated herein by reference.
 *
 */

#define DRV_NAME		"3c527"
#define DRV_VERSION		"0.7-SMP"
#define DRV_RELDATE		"2003/09/21"

static const char *version =
DRV_NAME ".c:v" DRV_VERSION " " DRV_RELDATE " Richard Procter <rnp@paradise.net.nz>\n";

/**
 * DOC: Traps for the unwary
 *
 *	The diagram (Figure 1-1) and the POS summary disagree with the
 *	"Interrupt Level" section in the manual.
 *
 *	The manual contradicts itself when describing the minimum number
 *	buffers in the 'configure lists' command.
 *	My card accepts a buffer config of 4/4.
 *
 *	Setting the SAV BP bit does not save bad packets, but
 *	only enables RX on-card stats collection.
 *
 *	The documentation in places seems to miss things. In actual fact
 *	I've always eventually found everything is documented, it just
 *	requires careful study.
 *
 * DOC: Theory Of Operation
 *
 *	The 3com 3c527 is a 32bit MCA bus mastering adapter with a large
 *	amount of on board intelligence that housekeeps a somewhat dumber
 *	Intel NIC. For performance we want to keep the transmit queue deep
 *	as the card can transmit packets while fetching others from main
 *	memory by bus master DMA. Transmission and reception are driven by
 *	circular buffer queues.
 *
 *	The mailboxes can be used for controlling how the card traverses
 *	its buffer rings, but are used only for inital setup in this
 *	implementation.  The exec mailbox allows a variety of commands to
 *	be executed. Each command must complete before the next is
 *	executed. Primarily we use the exec mailbox for controlling the
 *	multicast lists.  We have to do a certain amount of interesting
 *	hoop jumping as the multicast list changes can occur in interrupt
 *	state when the card has an exec command pending. We defer such
 *	events until the command completion interrupt.
 *
 *	A copy break scheme (taken from 3c59x.c) is employed whereby
 *	received frames exceeding a configurable length are passed
 *	directly to the higher networking layers without incuring a copy,
 *	in what amounts to a time/space trade-off.
 *
 *	The card also keeps a large amount of statistical information
 *	on-board. In a perfect world, these could be used safely at no
 *	cost. However, lacking information to the contrary, processing
 *	them without races would involve so much extra complexity as to
 *	make it unworthwhile to do so. In the end, a hybrid SW/HW
 *	implementation was made necessary --- see mc32_update_stats().
 *
 * DOC: Notes
 *
 *	It should be possible to use two or more cards, but at this stage
 *	only by loading two copies of the same module.
 *
 *	The on-board 82586 NIC has trouble receiving multiple
 *	back-to-back frames and so is likely to drop packets from fast
 *	senders.
**/

#include <linux/module.h>

#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/mca-legacy.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/wait.h>
#include <linux/ethtool.h>
#include <linux/completion.h>
#include <linux/bitops.h>

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

#include "3c527.h"

MODULE_LICENSE("GPL");

/*
 * The name of the card. Is used for messages and in the requests for
 * io regions, irqs and dma channels
 */
static const char* cardname = DRV_NAME;

/* use 0 for production, 1 for verification, >2 for debug */
#ifndef NET_DEBUG
#define NET_DEBUG 2
#endif

#undef DEBUG_IRQ

static unsigned int mc32_debug = NET_DEBUG;

/* The number of low I/O ports used by the ethercard. */
#define MC32_IO_EXTENT	8

/* As implemented, values must be a power-of-2 -- 4/8/16/32 */
#define TX_RING_LEN     32       /* Typically the card supports 37  */
#define RX_RING_LEN     8        /*     "       "        "          */

/* Copy break point, see above for details.
 * Setting to > 1512 effectively disables this feature.	*/
#define RX_COPYBREAK    200      /* Value from 3c59x.c */

/* Issue the 82586 workaround command - this is for "busy lans", but
 * basically means for all lans now days - has a performance (latency)
 * cost, but best set. */
static const int WORKAROUND_82586=1;

/* Pointers to buffers and their on-card records */
struct mc32_ring_desc
{
	volatile struct skb_header *p;
	struct sk_buff *skb;
};

/* Information that needs to be kept for each board. */
struct mc32_local
{
	int slot;

	u32 base;
	struct net_device_stats net_stats;
	volatile struct mc32_mailbox *rx_box;
	volatile struct mc32_mailbox *tx_box;
	volatile struct mc32_mailbox *exec_box;
        volatile struct mc32_stats *stats;    /* Start of on-card statistics */
        u16 tx_chain;           /* Transmit list start offset */
	u16 rx_chain;           /* Receive list start offset */
        u16 tx_len;             /* Transmit list count */
        u16 rx_len;             /* Receive list count */

	u16 xceiver_desired_state; /* HALTED or RUNNING */
	u16 cmd_nonblocking;    /* Thread is uninterested in command result */
	u16 mc_reload_wait;	/* A multicast load request is pending */
	u32 mc_list_valid;	/* True when the mclist is set */

	struct mc32_ring_desc tx_ring[TX_RING_LEN];	/* Host Transmit ring */
	struct mc32_ring_desc rx_ring[RX_RING_LEN];	/* Host Receive ring */

	atomic_t tx_count;	/* buffers left */
	atomic_t tx_ring_head;  /* index to tx en-queue end */
	u16 tx_ring_tail;       /* index to tx de-queue end */

	u16 rx_ring_tail;       /* index to rx de-queue end */

	struct semaphore cmd_mutex;    /* Serialises issuing of execute commands */
        struct completion execution_cmd; /* Card has completed an execute command */
	struct completion xceiver_cmd;   /* Card has completed a tx or rx command */
};

/* The station (ethernet) address prefix, used for a sanity check. */
#define SA_ADDR0 0x02
#define SA_ADDR1 0x60
#define SA_ADDR2 0xAC

struct mca_adapters_t {
	unsigned int	id;
	char		*name;
};

static const struct mca_adapters_t mc32_adapters[] = {
	{ 0x0041, "3COM EtherLink MC/32" },
	{ 0x8EF5, "IBM High Performance Lan Adapter" },
	{ 0x0000, NULL }
};


/* Macros for ring index manipulations */
static inline u16 next_rx(u16 rx) { return (rx+1)&(RX_RING_LEN-1); };
static inline u16 prev_rx(u16 rx) { return (rx-1)&(RX_RING_LEN-1); };

static inline u16 next_tx(u16 tx) { return (tx+1)&(TX_RING_LEN-1); };


/* Index to functions, as function prototypes. */
static int	mc32_probe1(struct net_device *dev, int ioaddr);
static int      mc32_command(struct net_device *dev, u16 cmd, void *data, int len);
static int	mc32_open(struct net_device *dev);
static void	mc32_timeout(struct net_device *dev);
static int	mc32_send_packet(struct sk_buff *skb, struct net_device *dev);
static irqreturn_t mc32_interrupt(int irq, void *dev_id);
static int	mc32_close(struct net_device *dev);
static struct	net_device_stats *mc32_get_stats(struct net_device *dev);
static void	mc32_set_multicast_list(struct net_device *dev);
static void	mc32_reset_multicast_list(struct net_device *dev);
static const struct ethtool_ops netdev_ethtool_ops;

static void cleanup_card(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	unsigned slot = lp->slot;
	mca_mark_as_unused(slot);
	mca_set_adapter_name(slot, NULL);
	free_irq(dev->irq, dev);
	release_region(dev->base_addr, MC32_IO_EXTENT);
}

/**
 * mc32_probe 	-	Search for supported boards
 * @unit: interface number to use
 *
 * Because MCA bus is a real bus and we can scan for cards we could do a
 * single scan for all boards here. Right now we use the passed in device
 * structure and scan for only one board. This needs fixing for modules
 * in particular.
 */

struct net_device *__init mc32_probe(int unit)
{
	struct net_device *dev = alloc_etherdev(sizeof(struct mc32_local));
	static int current_mca_slot = -1;
	int i;
	int err;

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

	if (unit >= 0)
		sprintf(dev->name, "eth%d", unit);

	/* Do not check any supplied i/o locations.
	   POS registers usually don't fail :) */

	/* MCA cards have POS registers.
	   Autodetecting MCA cards is extremely simple.
	   Just search for the card. */

	for(i = 0; (mc32_adapters[i].name != NULL); i++) {
		current_mca_slot =
			mca_find_unused_adapter(mc32_adapters[i].id, 0);

		if(current_mca_slot != MCA_NOTFOUND) {
			if(!mc32_probe1(dev, current_mca_slot))
			{
				mca_set_adapter_name(current_mca_slot,
						mc32_adapters[i].name);
				mca_mark_as_used(current_mca_slot);
				err = register_netdev(dev);
				if (err) {
					cleanup_card(dev);
					free_netdev(dev);
					dev = ERR_PTR(err);
				}
				return dev;
			}

		}
	}
	free_netdev(dev);
	return ERR_PTR(-ENODEV);
}

/**
 * mc32_probe1	-	Check a given slot for a board and test the card
 * @dev:  Device structure to fill in
 * @slot: The MCA bus slot being used by this card
 *
 * Decode the slot data and configure the card structures. Having done this we
 * can reset the card and configure it. The card does a full self test cycle
 * in firmware so we have to wait for it to return and post us either a
 * failure case or some addresses we use to find the board internals.
 */

static int __init mc32_probe1(struct net_device *dev, int slot)
{
	static unsigned version_printed;
	int i, err;
	u8 POS;
	u32 base;
	struct mc32_local *lp = netdev_priv(dev);
	static u16 mca_io_bases[]={
		0x7280,0x7290,
		0x7680,0x7690,
		0x7A80,0x7A90,
		0x7E80,0x7E90
	};
	static u32 mca_mem_bases[]={
		0x00C0000,
		0x00C4000,
		0x00C8000,
		0x00CC000,
		0x00D0000,
		0x00D4000,
		0x00D8000,
		0x00DC000
	};
	static char *failures[]={
		"Processor instruction",
		"Processor data bus",
		"Processor data bus",
		"Processor data bus",
		"Adapter bus",
		"ROM checksum",
		"Base RAM",
		"Extended RAM",
		"82586 internal loopback",
		"82586 initialisation failure",
		"Adapter list configuration error"
	};

	/* Time to play MCA games */

	if (mc32_debug  &&  version_printed++ == 0)
		printk(KERN_DEBUG "%s", version);

	printk(KERN_INFO "%s: %s found in slot %d:", dev->name, cardname, slot);

	POS = mca_read_stored_pos(slot, 2);

	if(!(POS&1))
	{
		printk(" disabled.\n");
		return -ENODEV;
	}

	/* Fill in the 'dev' fields. */
	dev->base_addr = mca_io_bases[(POS>>1)&7];
	dev->mem_start = mca_mem_bases[(POS>>4)&7];

	POS = mca_read_stored_pos(slot, 4);
	if(!(POS&1))
	{
		printk("memory window disabled.\n");
		return -ENODEV;
	}

	POS = mca_read_stored_pos(slot, 5);

	i=(POS>>4)&3;
	if(i==3)
	{
		printk("invalid memory window.\n");
		return -ENODEV;
	}

	i*=16384;
	i+=16384;

	dev->mem_end=dev->mem_start + i;

	dev->irq = ((POS>>2)&3)+9;

	if(!request_region(dev->base_addr, MC32_IO_EXTENT, cardname))
	{
		printk("io 0x%3lX, which is busy.\n", dev->base_addr);
		return -EBUSY;
	}

	printk("io 0x%3lX irq %d mem 0x%lX (%dK)\n",
		dev->base_addr, dev->irq, dev->mem_start, i/1024);


	/* We ought to set the cache line size here.. */


	/*
	 *	Go PROM browsing
	 */

	printk("%s: Address ", dev->name);

	/* Retrieve and print the ethernet address. */
	for (i = 0; i < 6; i++)
	{
		mca_write_pos(slot, 6, i+12);
		mca_write_pos(slot, 7, 0);

		printk(" %2.2x", dev->dev_addr[i] = mca_read_pos(slot,3));
	}

	mca_write_pos(slot, 6, 0);
	mca_write_pos(slot, 7, 0);

	POS = mca_read_stored_pos(slot, 4);

	if(POS&2)
		printk(" : BNC port selected.\n");
	else
		printk(" : AUI port selected.\n");

	POS=inb(dev->base_addr+HOST_CTRL);
	POS|=HOST_CTRL_ATTN|HOST_CTRL_RESET;
	POS&=~HOST_CTRL_INTE;
	outb(POS, dev->base_addr+HOST_CTRL);
	/* Reset adapter */
	udelay(100);
	/* Reset off */
	POS&=~(HOST_CTRL_ATTN|HOST_CTRL_RESET);
	outb(POS, dev->base_addr+HOST_CTRL);

	udelay(300);

	/*
	 *	Grab the IRQ
	 */

	err = request_irq(dev->irq, &mc32_interrupt, IRQF_SHARED | IRQF_SAMPLE_RANDOM, DRV_NAME, dev);
	if (err) {
		release_region(dev->base_addr, MC32_IO_EXTENT);
		printk(KERN_ERR "%s: unable to get IRQ %d.\n", DRV_NAME, dev->irq);
		goto err_exit_ports;
	}

	memset(lp, 0, sizeof(struct mc32_local));
	lp->slot = slot;

	i=0;

	base = inb(dev->base_addr);

	while(base == 0xFF)
	{
		i++;
		if(i == 1000)
		{
			printk(KERN_ERR "%s: failed to boot adapter.\n", dev->name);
			err = -ENODEV;
			goto err_exit_irq;
		}
		udelay(1000);
		if(inb(dev->base_addr+2)&(1<<5))
			base = inb(dev->base_addr);
	}

	if(base>0)
	{
		if(base < 0x0C)
			printk(KERN_ERR "%s: %s%s.\n", dev->name, failures[base-1],
				base<0x0A?" test failure":"");
		else
			printk(KERN_ERR "%s: unknown failure %d.\n", dev->name, base);
		err = -ENODEV;
		goto err_exit_irq;
	}

	base=0;
	for(i=0;i<4;i++)
	{
		int n=0;

		while(!(inb(dev->base_addr+2)&(1<<5)))
		{
			n++;
			udelay(50);
			if(n>100)
			{
				printk(KERN_ERR "%s: mailbox read fail (%d).\n", dev->name, i);
				err = -ENODEV;
				goto err_exit_irq;
			}
		}

		base|=(inb(dev->base_addr)<<(8*i));
	}

	lp->exec_box=isa_bus_to_virt(dev->mem_start+base);

	base=lp->exec_box->data[1]<<16|lp->exec_box->data[0];

	lp->base = dev->mem_start+base;

	lp->rx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[2]);
	lp->tx_box=isa_bus_to_virt(lp->base + lp->exec_box->data[3]);

	lp->stats = isa_bus_to_virt(lp->base + lp->exec_box->data[5]);

	/*
	 *	Descriptor chains (card relative)
	 */

	lp->tx_chain 		= lp->exec_box->data[8];   /* Transmit list start offset */
	lp->rx_chain 		= lp->exec_box->data[10];  /* Receive list start offset */
	lp->tx_len 		= lp->exec_box->data[9];   /* Transmit list count */
	lp->rx_len 		= lp->exec_box->data[11];  /* Receive list count */

	init_MUTEX_LOCKED(&lp->cmd_mutex);
	init_completion(&lp->execution_cmd);
	init_completion(&lp->xceiver_cmd);

	printk("%s: Firmware Rev %d. %d RX buffers, %d TX buffers. Base of 0x%08X.\n",
		dev->name, lp->exec_box->data[12], lp->rx_len, lp->tx_len, lp->base);

	dev->open		= mc32_open;
	dev->stop		= mc32_close;
	dev->hard_start_xmit	= mc32_send_packet;
	dev->get_stats		= mc32_get_stats;
	dev->set_multicast_list = mc32_set_multicast_list;
	dev->tx_timeout		= mc32_timeout;
	dev->watchdog_timeo	= HZ*5;	/* Board does all the work */
	dev->ethtool_ops	= &netdev_ethtool_ops;

	return 0;

err_exit_irq:
	free_irq(dev->irq, dev);
err_exit_ports:
	release_region(dev->base_addr, MC32_IO_EXTENT);
	return err;
}


/**
 *	mc32_ready_poll		-	wait until we can feed it a command
 *	@dev:	The device to wait for
 *
 *	Wait until the card becomes ready to accept a command via the
 *	command register. This tells us nothing about the completion
 *	status of any pending commands and takes very little time at all.
 */

static inline void mc32_ready_poll(struct net_device *dev)
{
	int ioaddr = dev->base_addr;
	while(!(inb(ioaddr+HOST_STATUS)&HOST_STATUS_CRR));
}


/**
 *	mc32_command_nowait	-	send a command non blocking
 *	@dev: The 3c527 to issue the command to
 *	@cmd: The command word to write to the mailbox
 *	@data: A data block if the command expects one
 *	@len: Length of the data block
 *
 *	Send a command from interrupt state. If there is a command
 *	currently being executed then we return an error of -1. It
 *	simply isn't viable to wait around as commands may be
 *	slow. This can theoretically be starved on SMP, but it's hard
 *	to see a realistic situation.  We do not wait for the command
 *	to complete --- we rely on the interrupt handler to tidy up
 *	after us.
 */

static int mc32_command_nowait(struct net_device *dev, u16 cmd, void *data, int len)
{
	struct mc32_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;
	int ret = -1;

	if (down_trylock(&lp->cmd_mutex) == 0)
	{
		lp->cmd_nonblocking=1;
		lp->exec_box->mbox=0;
		lp->exec_box->mbox=cmd;
		memcpy((void *)lp->exec_box->data, data, len);
		barrier();	/* the memcpy forgot the volatile so be sure */

		/* Send the command */
		mc32_ready_poll(dev);
		outb(1<<6, ioaddr+HOST_CMD);

		ret = 0;

		/* Interrupt handler will signal mutex on completion */
	}

	return ret;
}


/**
 *	mc32_command	-	send a command and sleep until completion
 *	@dev: The 3c527 card to issue the command to
 *	@cmd: The command word to write to the mailbox
 *	@data: A data block if the command expects one
 *	@len: Length of the data block
 *
 *	Sends exec commands in a user context. This permits us to wait around
 *	for the replies and also to wait for the command buffer to complete
 *	from a previous command before we execute our command. After our
 *	command completes we will attempt any pending multicast reload
 *	we blocked off by hogging the exec buffer.
 *
 *	You feed the card a command, you wait, it interrupts you get a
 *	reply. All well and good. The complication arises because you use
 *	commands for filter list changes which come in at bh level from things
 *	like IPV6 group stuff.
 */

static int mc32_command(struct net_device *dev, u16 cmd, void *data, int len)
{
	struct mc32_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;
	int ret = 0;

	down(&lp->cmd_mutex);

	/*
	 *     My Turn
	 */

	lp->cmd_nonblocking=0;
	lp->exec_box->mbox=0;
	lp->exec_box->mbox=cmd;
	memcpy((void *)lp->exec_box->data, data, len);
	barrier();	/* the memcpy forgot the volatile so be sure */

	mc32_ready_poll(dev);
	outb(1<<6, ioaddr+HOST_CMD);

	wait_for_completion(&lp->execution_cmd);

	if(lp->exec_box->mbox&(1<<13))
		ret = -1;

	up(&lp->cmd_mutex);

	/*
	 *	A multicast set got blocked - try it now
         */

	if(lp->mc_reload_wait)
	{
		mc32_reset_multicast_list(dev);
	}

	return ret;
}


/**
 *	mc32_start_transceiver	-	tell board to restart tx/rx
 *	@dev: The 3c527 card to issue the command to
 *
 *	This may be called from the interrupt state, where it is used
 *	to restart the rx ring if the card runs out of rx buffers.
 *
 * 	We must first check if it's ok to (re)start the transceiver. See
 *      mc32_close for details.
 */

static void mc32_start_transceiver(struct net_device *dev) {

	struct mc32_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;

	/* Ignore RX overflow on device closure */
	if (lp->xceiver_desired_state==HALTED)
		return;

	/* Give the card the offset to the post-EOL-bit RX descriptor */
	mc32_ready_poll(dev);
	lp->rx_box->mbox=0;
	lp->rx_box->data[0]=lp->rx_ring[prev_rx(lp->rx_ring_tail)].p->next;
	outb(HOST_CMD_START_RX, ioaddr+HOST_CMD);

	mc32_ready_poll(dev);
	lp->tx_box->mbox=0;
	outb(HOST_CMD_RESTRT_TX, ioaddr+HOST_CMD);   /* card ignores this on RX restart */

	/* We are not interrupted on start completion */
}


/**
 *	mc32_halt_transceiver	-	tell board to stop tx/rx
 *	@dev: The 3c527 card to issue the command to
 *
 *	We issue the commands to halt the card's transceiver. In fact,
 *	after some experimenting we now simply tell the card to
 *	suspend. When issuing aborts occasionally odd things happened.
 *
 *	We then sleep until the card has notified us that both rx and
 *	tx have been suspended.
 */

static void mc32_halt_transceiver(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;

	mc32_ready_poll(dev);
	lp->rx_box->mbox=0;
	outb(HOST_CMD_SUSPND_RX, ioaddr+HOST_CMD);
	wait_for_completion(&lp->xceiver_cmd);

	mc32_ready_poll(dev);
	lp->tx_box->mbox=0;
	outb(HOST_CMD_SUSPND_TX, ioaddr+HOST_CMD);
	wait_for_completion(&lp->xceiver_cmd);
}


/**
 *	mc32_load_rx_ring	-	load the ring of receive buffers
 *	@dev: 3c527 to build the ring for
 *
 *	This initalises the on-card and driver datastructures to
 *	the point where mc32_start_transceiver() can be called.
 *
 *	The card sets up the receive ring for us. We are required to use the
 *	ring it provides, although the size of the ring is configurable.
 *
 * 	We allocate an sk_buff for each ring entry in turn and
 * 	initalise its house-keeping info. At the same time, we read
 * 	each 'next' pointer in our rx_ring array. This reduces slow
 * 	shared-memory reads and makes it easy to access predecessor
 * 	descriptors.
 *
 *	We then set the end-of-list bit for the last entry so that the
 * 	card will know when it has run out of buffers.
 */

static int mc32_load_rx_ring(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	int i;
	u16 rx_base;
	volatile struct skb_header *p;

	rx_base=lp->rx_chain;

	for(i=0; i<RX_RING_LEN; i++) {
		lp->rx_ring[i].skb=alloc_skb(1532, GFP_KERNEL);
		if (lp->rx_ring[i].skb==NULL) {
			for (;i>=0;i--)
				kfree_skb(lp->rx_ring[i].skb);
			return -ENOBUFS;
		}
		skb_reserve(lp->rx_ring[i].skb, 18);

		p=isa_bus_to_virt(lp->base+rx_base);

		p->control=0;
		p->data=isa_virt_to_bus(lp->rx_ring[i].skb->data);
		p->status=0;
		p->length=1532;

		lp->rx_ring[i].p=p;
		rx_base=p->next;
	}

	lp->rx_ring[i-1].p->control |= CONTROL_EOL;

	lp->rx_ring_tail=0;

	return 0;
}


/**
 *	mc32_flush_rx_ring	-	free the ring of receive buffers
 *	@lp: Local data of 3c527 to flush the rx ring of
 *
 *	Free the buffer for each ring slot. This may be called
 *      before mc32_load_rx_ring(), eg. on error in mc32_open().
 *      Requires rx skb pointers to point to a valid skb, or NULL.
 */

static void mc32_flush_rx_ring(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	int i;

	for(i=0; i < RX_RING_LEN; i++)
	{
		if (lp->rx_ring[i].skb) {
			dev_kfree_skb(lp->rx_ring[i].skb);
			lp->rx_ring[i].skb = NULL;
		}
		lp->rx_ring[i].p=NULL;
	}
}


/**
 *	mc32_load_tx_ring	-	load transmit ring
 *	@dev: The 3c527 card to issue the command to
 *
 *	This sets up the host transmit data-structures.
 *
 *	First, we obtain from the card it's current postion in the tx
 *	ring, so that we will know where to begin transmitting
 *	packets.
 *
 * 	Then, we read the 'next' pointers from the on-card tx ring into
 *  	our tx_ring array to reduce slow shared-mem reads. Finally, we
 * 	intitalise the tx house keeping variables.
 *
 */

static void mc32_load_tx_ring(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	volatile struct skb_header *p;
	int i;
	u16 tx_base;

	tx_base=lp->tx_box->data[0];

	for(i=0 ; i<TX_RING_LEN ; i++)
	{
		p=isa_bus_to_virt(lp->base+tx_base);
		lp->tx_ring[i].p=p;
		lp->tx_ring[i].skb=NULL;

		tx_base=p->next;
	}

	/* -1 so that tx_ring_head cannot "lap" tx_ring_tail */
	/* see mc32_tx_ring */

	atomic_set(&lp->tx_count, TX_RING_LEN-1);
	atomic_set(&lp->tx_ring_head, 0);
	lp->tx_ring_tail=0;
}


/**
 *	mc32_flush_tx_ring 	-	free transmit ring
 *	@lp: Local data of 3c527 to flush the tx ring of
 *
 *      If the ring is non-empty, zip over the it, freeing any
 *      allocated skb_buffs.  The tx ring house-keeping variables are
 *      then reset. Requires rx skb pointers to point to a valid skb,
 *      or NULL.
 */

static void mc32_flush_tx_ring(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	int i;

	for (i=0; i < TX_RING_LEN; i++)
	{
		if (lp->tx_ring[i].skb)
		{
			dev_kfree_skb(lp->tx_ring[i].skb);
			lp->tx_ring[i].skb = NULL;
		}
	}

	atomic_set(&lp->tx_count, 0);
	atomic_set(&lp->tx_ring_head, 0);
	lp->tx_ring_tail=0;
}


/**
 *	mc32_open	-	handle 'up' of card
 *	@dev: device to open
 *
 *	The user is trying to bring the card into ready state. This requires
 *	a brief dialogue with the card. Firstly we enable interrupts and then
 *	'indications'. Without these enabled the card doesn't bother telling
 *	us what it has done. This had me puzzled for a week.
 *
 *	We configure the number of card descriptors, then load the network
 *	address and multicast filters. Turn on the workaround mode. This
 *	works around a bug in the 82586 - it asks the firmware to do
 *	so. It has a performance (latency) hit but is needed on busy
 *	[read most] lans. We load the ring with buffers then we kick it
 *	all off.
 */

static int mc32_open(struct net_device *dev)
{
	int ioaddr = dev->base_addr;
	struct mc32_local *lp = netdev_priv(dev);
	u8 one=1;
	u8 regs;
	u16 descnumbuffs[2] = {TX_RING_LEN, RX_RING_LEN};

	/*
	 *	Interrupts enabled
	 */

	regs=inb(ioaddr+HOST_CTRL);
	regs|=HOST_CTRL_INTE;
	outb(regs, ioaddr+HOST_CTRL);

	/*
	 *      Allow ourselves to issue commands
	 */

	up(&lp->cmd_mutex);


	/*
	 *	Send the indications on command
	 */

	mc32_command(dev, 4, &one, 2);

	/*
	 *	Poke it to make sure it's really dead.
	 */

	mc32_halt_transceiver(dev);
	mc32_flush_tx_ring(dev);

	/*
	 *	Ask card to set up on-card descriptors to our spec
	 */

	if(mc32_command(dev, 8, descnumbuffs, 4)) {
		printk("%s: %s rejected our buffer configuration!\n",
	 	       dev->name, cardname);
		mc32_close(dev);
		return -ENOBUFS;
	}

	/* Report new configuration */
	mc32_command(dev, 6, NULL, 0);

	lp->tx_chain 		= lp->exec_box->data[8];   /* Transmit list start offset */
	lp->rx_chain 		= lp->exec_box->data[10];  /* Receive list start offset */
	lp->tx_len 		= lp->exec_box->data[9];   /* Transmit list count */
	lp->rx_len 		= lp->exec_box->data[11];  /* Receive list count */

	/* Set Network Address */
	mc32_command(dev, 1, dev->dev_addr, 6);

	/* Set the filters */
	mc32_set_multicast_list(dev);

	if (WORKAROUND_82586) {
		u16 zero_word=0;
		mc32_command(dev, 0x0D, &zero_word, 2);   /* 82586 bug workaround on  */
	}

	mc32_load_tx_ring(dev);

	if(mc32_load_rx_ring(dev))
	{
		mc32_close(dev);
		return -ENOBUFS;
	}

	lp->xceiver_desired_state = RUNNING;

	/* And finally, set the ball rolling... */
	mc32_start_transceiver(dev);

	netif_start_queue(dev);

	return 0;
}


/**
 *	mc32_timeout	-	handle a timeout from the network layer
 *	@dev: 3c527 that timed out
 *
 *	Handle a timeout on transmit from the 3c527. This normally means
 *	bad things as the hardware handles cable timeouts and mess for
 *	us.
 *
 */

static void mc32_timeout(struct net_device *dev)
{
	printk(KERN_WARNING "%s: transmit timed out?\n", dev->name);
	/* Try to restart the adaptor. */
	netif_wake_queue(dev);
}


/**
 *	mc32_send_packet	-	queue a frame for transmit
 *	@skb: buffer to transmit
 *	@dev: 3c527 to send it out of
 *
 *	Transmit a buffer. This normally means throwing the buffer onto
 *	the transmit queue as the queue is quite large. If the queue is
 *	full then we set tx_busy and return. Once the interrupt handler
 *	gets messages telling it to reclaim transmit queue entries, we will
 *	clear tx_busy and the kernel will start calling this again.
 *
 *      We do not disable interrupts or acquire any locks; this can
 *      run concurrently with mc32_tx_ring(), and the function itself
 *      is serialised at a higher layer. However, similarly for the
 *      card itself, we must ensure that we update tx_ring_head only
 *      after we've established a valid packet on the tx ring (and
 *      before we let the card "see" it, to prevent it racing with the
 *      irq handler).
 *
 */

static int mc32_send_packet(struct sk_buff *skb, struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	u32 head = atomic_read(&lp->tx_ring_head);

	volatile struct skb_header *p, *np;

	netif_stop_queue(dev);

	if(atomic_read(&lp->tx_count)==0) {
		return 1;
	}

	if (skb_padto(skb, ETH_ZLEN)) {
		netif_wake_queue(dev);
		return 0;
	}

	atomic_dec(&lp->tx_count);

	/* P is the last sending/sent buffer as a pointer */
	p=lp->tx_ring[head].p;

	head = next_tx(head);

	/* NP is the buffer we will be loading */
	np=lp->tx_ring[head].p;

	/* We will need this to flush the buffer out */
	lp->tx_ring[head].skb=skb;

	np->length      = unlikely(skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
	np->data	= isa_virt_to_bus(skb->data);
	np->status	= 0;
	np->control     = CONTROL_EOP | CONTROL_EOL;
	wmb();

	/*
	 * The new frame has been setup; we can now
	 * let the interrupt handler and card "see" it
	 */

	atomic_set(&lp->tx_ring_head, head);
	p->control     &= ~CONTROL_EOL;

	netif_wake_queue(dev);
	return 0;
}


/**
 *	mc32_update_stats	-	pull off the on board statistics
 *	@dev: 3c527 to service
 *
 *
 *	Query and reset the on-card stats. There's the small possibility
 *	of a race here, which would result in an underestimation of
 *	actual errors. As such, we'd prefer to keep all our stats
 *	collection in software. As a rule, we do. However it can't be
 *	used for rx errors and collisions as, by default, the card discards
 *	bad rx packets.
 *
 *	Setting the SAV BP in the rx filter command supposedly
 *	stops this behaviour. However, testing shows that it only seems to
 *	enable the collation of on-card rx statistics --- the driver
 *	never sees an RX descriptor with an error status set.
 *
 */

static void mc32_update_stats(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	volatile struct mc32_stats *st = lp->stats;

	u32 rx_errors=0;

	rx_errors+=lp->net_stats.rx_crc_errors   +=st->rx_crc_errors;
	                                           st->rx_crc_errors=0;
	rx_errors+=lp->net_stats.rx_fifo_errors  +=st->rx_overrun_errors;
	                                           st->rx_overrun_errors=0;
	rx_errors+=lp->net_stats.rx_frame_errors +=st->rx_alignment_errors;
 	                                           st->rx_alignment_errors=0;
	rx_errors+=lp->net_stats.rx_length_errors+=st->rx_tooshort_errors;
	                                           st->rx_tooshort_errors=0;
	rx_errors+=lp->net_stats.rx_missed_errors+=st->rx_outofresource_errors;
	                                           st->rx_outofresource_errors=0;
        lp->net_stats.rx_errors=rx_errors;

	/* Number of packets which saw one collision */
	lp->net_stats.collisions+=st->dataC[10];
	st->dataC[10]=0;

	/* Number of packets which saw 2--15 collisions */
	lp->net_stats.collisions+=st->dataC[11];
	st->dataC[11]=0;
}


/**
 *	mc32_rx_ring	-	process the receive ring
 *	@dev: 3c527 that needs its receive ring processing
 *
 *
 *	We have received one or more indications from the card that a
 *	receive has completed. The buffer ring thus contains dirty
 *	entries. We walk the ring by iterating over the circular rx_ring
 *	array, starting at the next dirty buffer (which happens to be the
 *	one we finished up at last time around).
 *
 *	For each completed packet, we will either copy it and pass it up
 * 	the stack or, if the packet is near MTU sized, we allocate
 *	another buffer and flip the old one up the stack.
 *
 *	We must succeed in keeping a buffer on the ring. If necessary we
 *	will toss a received packet rather than lose a ring entry. Once
 *	the first uncompleted descriptor is found, we move the
 *	End-Of-List bit to include the buffers just processed.
 *
 */

static void mc32_rx_ring(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	volatile struct skb_header *p;
	u16 rx_ring_tail;
	u16 rx_old_tail;
	int x=0;

	rx_old_tail = rx_ring_tail = lp->rx_ring_tail;

	do
	{
		p=lp->rx_ring[rx_ring_tail].p;

		if(!(p->status & (1<<7))) { /* Not COMPLETED */
			break;
		}
		if(p->status & (1<<6)) /* COMPLETED_OK */
		{

			u16 length=p->length;
			struct sk_buff *skb;
			struct sk_buff *newskb;

			/* Try to save time by avoiding a copy on big frames */

			if ((length > RX_COPYBREAK)
			    && ((newskb=dev_alloc_skb(1532)) != NULL))
			{
				skb=lp->rx_ring[rx_ring_tail].skb;
				skb_put(skb, length);

				skb_reserve(newskb,18);
				lp->rx_ring[rx_ring_tail].skb=newskb;
				p->data=isa_virt_to_bus(newskb->data);
			}
			else
			{
				skb=dev_alloc_skb(length+2);

				if(skb==NULL) {
					lp->net_stats.rx_dropped++;
					goto dropped;
				}

				skb_reserve(skb,2);
				memcpy(skb_put(skb, length),
				       lp->rx_ring[rx_ring_tail].skb->data, length);
			}

			skb->protocol=eth_type_trans(skb,dev);
			dev->last_rx = jiffies;
 			lp->net_stats.rx_packets++;
 			lp->net_stats.rx_bytes += length;
			netif_rx(skb);
		}

	dropped:
		p->length = 1532;
		p->status = 0;

		rx_ring_tail=next_rx(rx_ring_tail);
	}
        while(x++<48);

	/* If there was actually a frame to be processed, place the EOL bit */
	/* at the descriptor prior to the one to be filled next */

	if (rx_ring_tail != rx_old_tail)
	{
		lp->rx_ring[prev_rx(rx_ring_tail)].p->control |=  CONTROL_EOL;
		lp->rx_ring[prev_rx(rx_old_tail)].p->control  &= ~CONTROL_EOL;

		lp->rx_ring_tail=rx_ring_tail;
	}
}


/**
 *	mc32_tx_ring	-	process completed transmits
 *	@dev: 3c527 that needs its transmit ring processing
 *
 *
 *	This operates in a similar fashion to mc32_rx_ring. We iterate
 *	over the transmit ring. For each descriptor which has been
 *	processed by the card, we free its associated buffer and note
 *	any errors. This continues until the transmit ring is emptied
 *	or we reach a descriptor that hasn't yet been processed by the
 *	card.
 *
 */

static void mc32_tx_ring(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	volatile struct skb_header *np;

	/*
	 * We rely on head==tail to mean 'queue empty'.
	 * This is why lp->tx_count=TX_RING_LEN-1: in order to prevent
	 * tx_ring_head wrapping to tail and confusing a 'queue empty'
	 * condition with 'queue full'
	 */

	while (lp->tx_ring_tail != atomic_read(&lp->tx_ring_head))
	{
		u16 t;

		t=next_tx(lp->tx_ring_tail);
		np=lp->tx_ring[t].p;

		if(!(np->status & (1<<7)))
		{
			/* Not COMPLETED */
			break;
		}
		lp->net_stats.tx_packets++;
		if(!(np->status & (1<<6))) /* Not COMPLETED_OK */
		{
			lp->net_stats.tx_errors++;

			switch(np->status&0x0F)
			{
				case 1:
					lp->net_stats.tx_aborted_errors++;
					break; /* Max collisions */
				case 2:
					lp->net_stats.tx_fifo_errors++;
					break;
				case 3:
					lp->net_stats.tx_carrier_errors++;
					break;
				case 4:
					lp->net_stats.tx_window_errors++;
					break;  /* CTS Lost */
				case 5:
					lp->net_stats.tx_aborted_errors++;
					break; /* Transmit timeout */
			}
		}
		/* Packets are sent in order - this is
		    basically a FIFO queue of buffers matching
		    the card ring */
		lp->net_stats.tx_bytes+=lp->tx_ring[t].skb->len;
		dev_kfree_skb_irq(lp->tx_ring[t].skb);
		lp->tx_ring[t].skb=NULL;
		atomic_inc(&lp->tx_count);
		netif_wake_queue(dev);

		lp->tx_ring_tail=t;
	}

}


/**
 *	mc32_interrupt		-	handle an interrupt from a 3c527
 *	@irq: Interrupt number
 *	@dev_id: 3c527 that requires servicing
 *	@regs: Registers (unused)
 *
 *
 *	An interrupt is raised whenever the 3c527 writes to the command
 *	register. This register contains the message it wishes to send us
 *	packed into a single byte field. We keep reading status entries
 *	until we have processed all the control items, but simply count
 *	transmit and receive reports. When all reports are in we empty the
 *	transceiver rings as appropriate. This saves the overhead of
 *	multiple command requests.
 *
 *	Because MCA is level-triggered, we shouldn't miss indications.
 *	Therefore, we needn't ask the card to suspend interrupts within
 *	this handler. The card receives an implicit acknowledgment of the
 *	current interrupt when we read the command register.
 *
 */

static irqreturn_t mc32_interrupt(int irq, void *dev_id)
{
	struct net_device *dev = dev_id;
	struct mc32_local *lp;
	int ioaddr, status, boguscount = 0;
	int rx_event = 0;
	int tx_event = 0;

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

	/* See whats cooking */

	while((inb(ioaddr+HOST_STATUS)&HOST_STATUS_CWR) && boguscount++<2000)
	{
		status=inb(ioaddr+HOST_CMD);

#ifdef DEBUG_IRQ
		printk("Status TX%d RX%d EX%d OV%d BC%d\n",
			(status&7), (status>>3)&7, (status>>6)&1,
			(status>>7)&1, boguscount);
#endif

		switch(status&7)
		{
			case 0:
				break;
			case 6: /* TX fail */
			case 2:	/* TX ok */
				tx_event = 1;
				break;
			case 3: /* Halt */
			case 4: /* Abort */
				complete(&lp->xceiver_cmd);
				break;
			default:
				printk("%s: strange tx ack %d\n", dev->name, status&7);
		}
		status>>=3;
		switch(status&7)
		{
			case 0:
				break;
			case 2:	/* RX */
				rx_event=1;
				break;
			case 3: /* Halt */
			case 4: /* Abort */
				complete(&lp->xceiver_cmd);
				break;
			case 6:
				/* Out of RX buffers stat */
				/* Must restart rx */
				lp->net_stats.rx_dropped++;
				mc32_rx_ring(dev);
				mc32_start_transceiver(dev);
				break;
			default:
				printk("%s: strange rx ack %d\n",
					dev->name, status&7);
		}
		status>>=3;
		if(status&1)
		{
			/*
			 * No thread is waiting: we need to tidy
			 * up ourself.
			 */

			if (lp->cmd_nonblocking) {
				up(&lp->cmd_mutex);
				if (lp->mc_reload_wait)
					mc32_reset_multicast_list(dev);
			}
			else complete(&lp->execution_cmd);
		}
		if(status&2)
		{
			/*
			 *	We get interrupted once per
			 *	counter that is about to overflow.
			 */

			mc32_update_stats(dev);
		}
	}


	/*
	 *	Process the transmit and receive rings
         */

	if(tx_event)
		mc32_tx_ring(dev);

	if(rx_event)
		mc32_rx_ring(dev);

	return IRQ_HANDLED;
}


/**
 *	mc32_close	-	user configuring the 3c527 down
 *	@dev: 3c527 card to shut down
 *
 *	The 3c527 is a bus mastering device. We must be careful how we
 *	shut it down. It may also be running shared interrupt so we have
 *	to be sure to silence it properly
 *
 *	We indicate that the card is closing to the rest of the
 *	driver.  Otherwise, it is possible that the card may run out
 *	of receive buffers and restart the transceiver while we're
 *	trying to close it.
 *
 *	We abort any receive and transmits going on and then wait until
 *	any pending exec commands have completed in other code threads.
 *	In theory we can't get here while that is true, in practice I am
 *	paranoid
 *
 *	We turn off the interrupt enable for the board to be sure it can't
 *	intefere with other devices.
 */

static int mc32_close(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;

	u8 regs;
	u16 one=1;

	lp->xceiver_desired_state = HALTED;
	netif_stop_queue(dev);

	/*
	 *	Send the indications on command (handy debug check)
	 */

	mc32_command(dev, 4, &one, 2);

	/* Shut down the transceiver */

	mc32_halt_transceiver(dev);

	/* Ensure we issue no more commands beyond this point */

	down(&lp->cmd_mutex);

	/* Ok the card is now stopping */

	regs=inb(ioaddr+HOST_CTRL);
	regs&=~HOST_CTRL_INTE;
	outb(regs, ioaddr+HOST_CTRL);

	mc32_flush_rx_ring(dev);
	mc32_flush_tx_ring(dev);

	mc32_update_stats(dev);

	return 0;
}


/**
 *	mc32_get_stats		-	hand back stats to network layer
 *	@dev: The 3c527 card to handle
 *
 *	We've collected all the stats we can in software already. Now
 *	it's time to update those kept on-card and return the lot.
 *
 */

static struct net_device_stats *mc32_get_stats(struct net_device *dev)
{
	struct mc32_local *lp = netdev_priv(dev);

	mc32_update_stats(dev);
	return &lp->net_stats;
}


/**
 *	do_mc32_set_multicast_list	-	attempt to update multicasts
 *	@dev: 3c527 device to load the list on
 *	@retry: indicates this is not the first call.
 *
 *
 * 	Actually set or clear the multicast filter for this adaptor. The
 *	locking issues are handled by this routine. We have to track
 *	state as it may take multiple calls to get the command sequence
 *	completed. We just keep trying to schedule the loads until we
 *	manage to process them all.
 *
 *	num_addrs == -1	Promiscuous mode, receive all packets
 *
 *	num_addrs == 0	Normal mode, clear multicast list
 *
 *	num_addrs > 0	Multicast mode, receive normal and MC packets,
 *			and do best-effort filtering.
 *
 *	See mc32_update_stats() regards setting the SAV BP bit.
 *
 */

static void do_mc32_set_multicast_list(struct net_device *dev, int retry)
{
	struct mc32_local *lp = netdev_priv(dev);
	u16 filt = (1<<2); /* Save Bad Packets, for stats purposes */

	if (dev->flags&IFF_PROMISC)
		/* Enable promiscuous mode */
		filt |= 1;
	else if((dev->flags&IFF_ALLMULTI) || dev->mc_count > 10)
	{
		dev->flags|=IFF_PROMISC;
		filt |= 1;
	}
	else if(dev->mc_count)
	{
		unsigned char block[62];
		unsigned char *bp;
		struct dev_mc_list *dmc=dev->mc_list;

		int i;

		if(retry==0)
			lp->mc_list_valid = 0;
		if(!lp->mc_list_valid)
		{
			block[1]=0;
			block[0]=dev->mc_count;
			bp=block+2;

			for(i=0;i<dev->mc_count;i++)
			{
				memcpy(bp, dmc->dmi_addr, 6);
				bp+=6;
				dmc=dmc->next;
			}
			if(mc32_command_nowait(dev, 2, block, 2+6*dev->mc_count)==-1)
			{
				lp->mc_reload_wait = 1;
				return;
			}
			lp->mc_list_valid=1;
		}
	}

	if(mc32_command_nowait(dev, 0, &filt, 2)==-1)
	{
		lp->mc_reload_wait = 1;
	}
	else {
		lp->mc_reload_wait = 0;
	}
}


/**
 *	mc32_set_multicast_list	-	queue multicast list update
 *	@dev: The 3c527 to use
 *
 *	Commence loading the multicast list. This is called when the kernel
 *	changes the lists. It will override any pending list we are trying to
 *	load.
 */

static void mc32_set_multicast_list(struct net_device *dev)
{
	do_mc32_set_multicast_list(dev,0);
}


/**
 *	mc32_reset_multicast_list	-	reset multicast list
 *	@dev: The 3c527 to use
 *
 *	Attempt the next step in loading the multicast lists. If this attempt
 *	fails to complete then it will be scheduled and this function called
 *	again later from elsewhere.
 */

static void mc32_reset_multicast_list(struct net_device *dev)
{
	do_mc32_set_multicast_list(dev,1);
}

static void netdev_get_drvinfo(struct net_device *dev,
			       struct ethtool_drvinfo *info)
{
	strcpy(info->driver, DRV_NAME);
	strcpy(info->version, DRV_VERSION);
	sprintf(info->bus_info, "MCA 0x%lx", dev->base_addr);
}

static u32 netdev_get_msglevel(struct net_device *dev)
{
	return mc32_debug;
}

static void netdev_set_msglevel(struct net_device *dev, u32 level)
{
	mc32_debug = level;
}

static const struct ethtool_ops netdev_ethtool_ops = {
	.get_drvinfo		= netdev_get_drvinfo,
	.get_msglevel		= netdev_get_msglevel,
	.set_msglevel		= netdev_set_msglevel,
};

#ifdef MODULE

static struct net_device *this_device;

/**
 *	init_module		-	entry point
 *
 *	Probe and locate a 3c527 card. This really should probe and locate
 *	all the 3c527 cards in the machine not just one of them. Yes you can
 *	insmod multiple modules for now but it's a hack.
 */

int __init init_module(void)
{
	this_device = mc32_probe(-1);
	if (IS_ERR(this_device))
		return PTR_ERR(this_device);
	return 0;
}

/**
 *	cleanup_module	-	free resources for an unload
 *
 *	Unloading time. We release the MCA bus resources and the interrupt
 *	at which point everything is ready to unload. The card must be stopped
 *	at this point or we would not have been called. When we unload we
 *	leave the card stopped but not totally shut down. When the card is
 *	initialized it must be rebooted or the rings reloaded before any
 *	transmit operations are allowed to start scribbling into memory.
 */

void __exit cleanup_module(void)
{
	unregister_netdev(this_device);
	cleanup_card(this_device);
	free_netdev(this_device);
}

#endif /* MODULE */
