/* 
net-3-driver for the SKNET MCA-based cards

This is an extension to the Linux operating system, and is covered by the
same GNU General Public License that covers that work.

Copyright 1999 by Alfred Arnold (alfred@ccac.rwth-aachen.de,
                                 alfred.arnold@lancom.de)

This driver is based both on the 3C523 driver and the SK_G16 driver.

paper sources:
  'PC Hardware: Aufbau, Funktionsweise, Programmierung' by 
  Hans-Peter Messmer for the basic Microchannel stuff
  
  'Linux Geraetetreiber' by Allesandro Rubini, Kalle Dalheimer
  for help on Ethernet driver programming

  'Ethernet/IEEE 802.3 Family 1992 World Network Data Book/Handbook' by AMD
  for documentation on the AM7990 LANCE

  'SKNET Personal Technisches Manual', Version 1.2 by Schneider&Koch
  for documentation on the Junior board

  'SK-NET MC2+ Technical Manual", Version 1.1 by Schneider&Koch for
  documentation on the MC2 bord
  
  A big thank you to the S&K support for providing me so quickly with
  documentation!

  Also see http://www.syskonnect.com/

  Missing things:

  -> set debug level via ioctl instead of compile-time switches
  -> I didn't follow the development of the 2.1.x kernels, so my
     assumptions about which things changed with which kernel version 
     are probably nonsense

History:
  May 16th, 1999
  	startup
  May 22st, 1999
	added private structure, methods
        begun building data structures in RAM
  May 23nd, 1999
	can receive frames, send frames
  May 24th, 1999
        modularized initialization of LANCE
        loadable as module
	still Tx problem :-(
  May 26th, 1999
  	MC2 works
  	support for multiple devices
  	display media type for MC2+
  May 28th, 1999
	fixed problem in GetLANCE leaving interrupts turned off
        increase TX queue to 4 packets to improve send performance
  May 29th, 1999
	a few corrections in statistics, caught rcvr overruns 
        reinitialization of LANCE/board in critical situations
        MCA info implemented
	implemented LANCE multicast filter
  Jun 6th, 1999
	additions for Linux 2.2
  Dec 25th, 1999
  	unfortunately there seem to be newer MC2+ boards that react
  	on IRQ 3/5/9/10 instead of 3/5/10/11, so we have to autoprobe
  	in questionable cases...
  Dec 28th, 1999
	integrated patches from David Weinehall & Bill Wendling for 2.3
	kernels (isa_...functions).  Things are defined in a way that
        it still works with 2.0.x 8-)
  Dec 30th, 1999
	added handling of the remaining interrupt conditions.  That
        should cure the spurious hangs.
  Jan 30th, 2000
	newer kernels automatically probe more than one board, so the
	'startslot' as a variable is also needed here
  June 1st, 2000
	added changes for recent 2.3 kernels

 *************************************************************************/

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/time.h>
#include <linux/mca-legacy.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/bitops.h>

#include <asm/processor.h>
#include <asm/io.h>

#define _SK_MCA_DRIVER_
#include "sk_mca.h"

/* ------------------------------------------------------------------------
 * global static data - not more since we can handle multiple boards and
 * have to pack all state info into the device struct!
 * ------------------------------------------------------------------------ */

static char *MediaNames[Media_Count] =
    { "10Base2", "10BaseT", "10Base5", "Unknown" };

static unsigned char poly[] =
    { 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 0, 0, 0,
	1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0
};

/* ------------------------------------------------------------------------
 * private subfunctions
 * ------------------------------------------------------------------------ */

/* dump parts of shared memory - only needed during debugging */

#ifdef DEBUG
static void dumpmem(struct net_device *dev, u32 start, u32 len)
{
	skmca_priv *priv = netdev_priv(dev);
	int z;

	for (z = 0; z < len; z++) {
		if ((z & 15) == 0)
			printk("%04x:", z);
		printk(" %02x", readb(priv->base + start + z));
		if ((z & 15) == 15)
			printk("\n");
	}
}

/* print exact time - ditto */

static void PrTime(void)
{
	struct timeval tv;

	do_gettimeofday(&tv);
	printk("%9d:%06d: ", tv.tv_sec, tv.tv_usec);
}
#endif

/* deduce resources out of POS registers */

static void __init getaddrs(int slot, int junior, int *base, int *irq,
		     skmca_medium * medium)
{
	u_char pos0, pos1, pos2;

	if (junior) {
		pos0 = mca_read_stored_pos(slot, 2);
		*base = ((pos0 & 0x0e) << 13) + 0xc0000;
		*irq = ((pos0 & 0x10) >> 4) + 10;
		*medium = Media_Unknown;
	} else {
		/* reset POS 104 Bits 0+1 so the shared memory region goes to the
		   configured area between 640K and 1M.  Afterwards, enable the MC2.
		   I really don't know what rode SK to do this... */

		mca_write_pos(slot, 4,
			      mca_read_stored_pos(slot, 4) & 0xfc);
		mca_write_pos(slot, 2,
			      mca_read_stored_pos(slot, 2) | 0x01);

		pos1 = mca_read_stored_pos(slot, 3);
		pos2 = mca_read_stored_pos(slot, 4);
		*base = ((pos1 & 0x07) << 14) + 0xc0000;
		switch (pos2 & 0x0c) {
		case 0:
			*irq = 3;
			break;
		case 4:
			*irq = 5;
			break;
		case 8:
			*irq = -10;
			break;
		case 12:
			*irq = -11;
			break;
		}
		*medium = (pos2 >> 6) & 3;
	}
}

/* check for both cards:
   When the MC2 is turned off, it was configured for more than 15MB RAM,
   is disabled and won't get detected using the standard probe.  We
   therefore have to scan the slots manually :-( */

static int __init dofind(int *junior, int firstslot)
{
	int slot;
	unsigned int id;

	for (slot = firstslot; slot < MCA_MAX_SLOT_NR; slot++) {
		id = mca_read_stored_pos(slot, 0)
		    + (((unsigned int) mca_read_stored_pos(slot, 1)) << 8);

		*junior = 0;
		if (id == SKNET_MCA_ID)
			return slot;
		*junior = 1;
		if (id == SKNET_JUNIOR_MCA_ID)
			return slot;
	}
	return MCA_NOTFOUND;
}

/* reset the whole board */

static void ResetBoard(struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);

	writeb(CTRL_RESET_ON, priv->ctrladdr);
	udelay(10);
	writeb(CTRL_RESET_OFF, priv->ctrladdr);
}

/* wait for LANCE interface to become not busy */

static int WaitLANCE(struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);
	int t = 0;

	while ((readb(priv->ctrladdr) & STAT_IO_BUSY) ==
	       STAT_IO_BUSY) {
		udelay(1);
		if (++t > 1000) {
			printk("%s: LANCE access timeout", dev->name);
			return 0;
		}
	}

	return 1;
}

/* set LANCE register - must be atomic */

static void SetLANCE(struct net_device *dev, u16 addr, u16 value)
{
	skmca_priv *priv = netdev_priv(dev);
	unsigned long flags;

	/* disable interrupts */

	spin_lock_irqsave(&priv->lock, flags);

	/* wait until no transfer is pending */

	WaitLANCE(dev);

	/* transfer register address to RAP */

	writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
	writew(addr, priv->ioregaddr);
	writeb(IOCMD_GO, priv->cmdaddr);
	udelay(1);
	WaitLANCE(dev);

	/* transfer data to register */

	writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA, priv->ctrladdr);
	writew(value, priv->ioregaddr);
	writeb(IOCMD_GO, priv->cmdaddr);
	udelay(1);
	WaitLANCE(dev);

	/* reenable interrupts */

	spin_unlock_irqrestore(&priv->lock, flags);
}

/* get LANCE register */

static u16 GetLANCE(struct net_device *dev, u16 addr)
{
	skmca_priv *priv = netdev_priv(dev);
	unsigned long flags;
	unsigned int res;

	/* disable interrupts */

	spin_lock_irqsave(&priv->lock, flags);

	/* wait until no transfer is pending */

	WaitLANCE(dev);

	/* transfer register address to RAP */

	writeb(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_RAP, priv->ctrladdr);
	writew(addr, priv->ioregaddr);
	writeb(IOCMD_GO, priv->cmdaddr);
	udelay(1);
	WaitLANCE(dev);

	/* transfer data from register */

	writeb(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA, priv->ctrladdr);
	writeb(IOCMD_GO, priv->cmdaddr);
	udelay(1);
	WaitLANCE(dev);
	res = readw(priv->ioregaddr);

	/* reenable interrupts */

	spin_unlock_irqrestore(&priv->lock, flags);

	return res;
}

/* build up descriptors in shared RAM */

static void InitDscrs(struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);
	u32 bufaddr;

	/* Set up Tx descriptors. The board has only 16K RAM so bits 16..23
	   are always 0. */

	bufaddr = RAM_DATABASE;
	{
		LANCE_TxDescr descr;
		int z;

		for (z = 0; z < TXCOUNT; z++) {
			descr.LowAddr = bufaddr;
			descr.Flags = 0;
			descr.Len = 0xf000;
			descr.Status = 0;
			memcpy_toio(priv->base + RAM_TXBASE +
				   (z * sizeof(LANCE_TxDescr)), &descr,
				   sizeof(LANCE_TxDescr));
			memset_io(priv->base + bufaddr, 0, RAM_BUFSIZE);
			bufaddr += RAM_BUFSIZE;
		}
	}

	/* do the same for the Rx descriptors */

	{
		LANCE_RxDescr descr;
		int z;

		for (z = 0; z < RXCOUNT; z++) {
			descr.LowAddr = bufaddr;
			descr.Flags = RXDSCR_FLAGS_OWN;
			descr.MaxLen = -RAM_BUFSIZE;
			descr.Len = 0;
			memcpy_toio(priv->base + RAM_RXBASE +
				   (z * sizeof(LANCE_RxDescr)), &descr,
				   sizeof(LANCE_RxDescr));
			memset_io(priv->base + bufaddr, 0, RAM_BUFSIZE);
			bufaddr += RAM_BUFSIZE;
		}
	}
}

/* calculate the hash bit position for a given multicast address
   taken more or less directly from the AMD datasheet... */

static void UpdateCRC(unsigned char *CRC, int bit)
{
	int j;

	/* shift CRC one bit */

	memmove(CRC + 1, CRC, 32 * sizeof(unsigned char));
	CRC[0] = 0;

	/* if bit XOR controlbit = 1, set CRC = CRC XOR polynomial */

	if (bit ^ CRC[32])
		for (j = 0; j < 32; j++)
			CRC[j] ^= poly[j];
}

static unsigned int GetHash(char *address)
{
	unsigned char CRC[33];
	int i, byte, hashcode;

	/* a multicast address has bit 0 in the first byte set */

	if ((address[0] & 1) == 0)
		return -1;

	/* initialize CRC */

	memset(CRC, 1, sizeof(CRC));

	/* loop through address bits */

	for (byte = 0; byte < 6; byte++)
		for (i = 0; i < 8; i++)
			UpdateCRC(CRC, (address[byte] >> i) & 1);

	/* hashcode is the 6 least significant bits of the CRC */

	hashcode = 0;
	for (i = 0; i < 6; i++)
		hashcode = (hashcode << 1) + CRC[i];
	return hashcode;
}

/* feed ready-built initialization block into LANCE */

static void InitLANCE(struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);

	/* build up descriptors. */

	InitDscrs(dev);

	/* next RX descriptor to be read is the first one.  Since the LANCE
	   will start from the beginning after initialization, we have to 
	   reset out pointers too. */

	priv->nextrx = 0;

	/* no TX descriptors active */

	priv->nexttxput = priv->nexttxdone = priv->txbusy = 0;

	/* set up the LANCE bus control register - constant for SKnet boards */

	SetLANCE(dev, LANCE_CSR3,
		 CSR3_BSWAP_OFF | CSR3_ALE_LOW | CSR3_BCON_HOLD);

	/* write address of initialization block into LANCE */

	SetLANCE(dev, LANCE_CSR1, RAM_INITBASE & 0xffff);
	SetLANCE(dev, LANCE_CSR2, (RAM_INITBASE >> 16) & 0xff);

	/* we don't get ready until the LANCE has read the init block */

	netif_stop_queue(dev);

	/* let LANCE read the initialization block.  LANCE is ready
	   when we receive the corresponding interrupt. */

	SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_INIT);
}

/* stop the LANCE so we can reinitialize it */

static void StopLANCE(struct net_device *dev)
{
	/* can't take frames any more */

	netif_stop_queue(dev);

	/* disable interrupts, stop it */

	SetLANCE(dev, LANCE_CSR0, CSR0_STOP);
}

/* initialize card and LANCE for proper operation */

static void InitBoard(struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);
	LANCE_InitBlock block;

	/* Lay out the shared RAM - first we create the init block for the LANCE.
	   We do not overwrite it later because we need it again when we switch
	   promiscous mode on/off. */

	block.Mode = 0;
	if (dev->flags & IFF_PROMISC)
		block.Mode |= LANCE_INIT_PROM;
	memcpy(block.PAdr, dev->dev_addr, 6);
	memset(block.LAdrF, 0, sizeof(block.LAdrF));
	block.RdrP = (RAM_RXBASE & 0xffffff) | (LRXCOUNT << 29);
	block.TdrP = (RAM_TXBASE & 0xffffff) | (LTXCOUNT << 29);

	memcpy_toio(priv->base + RAM_INITBASE, &block, sizeof(block));

	/* initialize LANCE. Implicitly sets up other structures in RAM. */

	InitLANCE(dev);
}

/* deinitialize card and LANCE */

static void DeinitBoard(struct net_device *dev)
{
	/* stop LANCE */

	StopLANCE(dev);

	/* reset board */

	ResetBoard(dev);
}

/* probe for device's irq */

static int __init ProbeIRQ(struct net_device *dev)
{
	unsigned long imaskval, njiffies, irq;
	u16 csr0val;

	/* enable all interrupts */

	imaskval = probe_irq_on();

	/* initialize the board. Wait for interrupt 'Initialization done'. */

	ResetBoard(dev);
	InitBoard(dev);

	njiffies = jiffies + HZ;
	do {
		csr0val = GetLANCE(dev, LANCE_CSR0);
	}
	while (((csr0val & CSR0_IDON) == 0) && (jiffies != njiffies));

	/* turn of interrupts again */

	irq = probe_irq_off(imaskval);

	/* if we found something, ack the interrupt */

	if (irq)
		SetLANCE(dev, LANCE_CSR0, csr0val | CSR0_IDON);

	/* back to idle state */

	DeinitBoard(dev);

	return irq;
}

/* ------------------------------------------------------------------------
 * interrupt handler(s)
 * ------------------------------------------------------------------------ */

/* LANCE has read initialization block -> start it */

static u16 irqstart_handler(struct net_device *dev, u16 oldcsr0)
{
	/* now we're ready to transmit */

	netif_wake_queue(dev);

	/* reset IDON bit, start LANCE */

	SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_IDON | CSR0_STRT);
	return GetLANCE(dev, LANCE_CSR0);
}

/* did we lose blocks due to a FIFO overrun ? */

static u16 irqmiss_handler(struct net_device *dev, u16 oldcsr0)
{
	skmca_priv *priv = netdev_priv(dev);

	/* update statistics */

	priv->stat.rx_fifo_errors++;

	/* reset MISS bit */

	SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_MISS);
	return GetLANCE(dev, LANCE_CSR0);
}

/* receive interrupt */

static u16 irqrx_handler(struct net_device *dev, u16 oldcsr0)
{
	skmca_priv *priv = netdev_priv(dev);
	LANCE_RxDescr descr;
	unsigned int descraddr;

	/* run through queue until we reach a descriptor we do not own */

	descraddr = RAM_RXBASE + (priv->nextrx * sizeof(LANCE_RxDescr));
	while (1) {
		/* read descriptor */
		memcpy_fromio(&descr, priv->base + descraddr,
			     sizeof(LANCE_RxDescr));

		/* if we reach a descriptor we do not own, we're done */
		if ((descr.Flags & RXDSCR_FLAGS_OWN) != 0)
			break;

#ifdef DEBUG
		PrTime();
		printk("Receive packet on descr %d len %d\n", priv->nextrx,
		       descr.Len);
#endif

		/* erroneous packet ? */
		if ((descr.Flags & RXDSCR_FLAGS_ERR) != 0) {
			priv->stat.rx_errors++;
			if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0)
				priv->stat.rx_crc_errors++;
			else if ((descr.Flags & RXDSCR_FLAGS_CRC) != 0)
				priv->stat.rx_frame_errors++;
			else if ((descr.Flags & RXDSCR_FLAGS_OFLO) != 0)
				priv->stat.rx_fifo_errors++;
		}

		/* good packet ? */
		else {
			struct sk_buff *skb;

			skb = dev_alloc_skb(descr.Len + 2);
			if (skb == NULL)
				priv->stat.rx_dropped++;
			else {
				memcpy_fromio(skb_put(skb, descr.Len),
					     priv->base +
					     descr.LowAddr, descr.Len);
				skb->dev = dev;
				skb->protocol = eth_type_trans(skb, dev);
				skb->ip_summed = CHECKSUM_NONE;
				priv->stat.rx_packets++;
				priv->stat.rx_bytes += descr.Len;
				netif_rx(skb);
				dev->last_rx = jiffies;
			}
		}

		/* give descriptor back to LANCE */
		descr.Len = 0;
		descr.Flags |= RXDSCR_FLAGS_OWN;

		/* update descriptor in shared RAM */
		memcpy_toio(priv->base + descraddr, &descr,
			   sizeof(LANCE_RxDescr));

		/* go to next descriptor */
		priv->nextrx++;
		descraddr += sizeof(LANCE_RxDescr);
		if (priv->nextrx >= RXCOUNT) {
			priv->nextrx = 0;
			descraddr = RAM_RXBASE;
		}
	}

	/* reset RINT bit */

	SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_RINT);
	return GetLANCE(dev, LANCE_CSR0);
}

/* transmit interrupt */

static u16 irqtx_handler(struct net_device *dev, u16 oldcsr0)
{
	skmca_priv *priv = netdev_priv(dev);
	LANCE_TxDescr descr;
	unsigned int descraddr;

	/* check descriptors at most until no busy one is left */

	descraddr =
	    RAM_TXBASE + (priv->nexttxdone * sizeof(LANCE_TxDescr));
	while (priv->txbusy > 0) {
		/* read descriptor */
		memcpy_fromio(&descr, priv->base + descraddr,
			     sizeof(LANCE_TxDescr));

		/* if the LANCE still owns this one, we've worked out all sent packets */
		if ((descr.Flags & TXDSCR_FLAGS_OWN) != 0)
			break;

#ifdef DEBUG
		PrTime();
		printk("Send packet done on descr %d\n", priv->nexttxdone);
#endif

		/* update statistics */
		if ((descr.Flags & TXDSCR_FLAGS_ERR) == 0) {
			priv->stat.tx_packets++;
			priv->stat.tx_bytes++;
		} else {
			priv->stat.tx_errors++;
			if ((descr.Status & TXDSCR_STATUS_UFLO) != 0) {
				priv->stat.tx_fifo_errors++;
				InitLANCE(dev);
			}
				else
			    if ((descr.Status & TXDSCR_STATUS_LCOL) !=
				0) priv->stat.tx_window_errors++;
			else if ((descr.Status & TXDSCR_STATUS_LCAR) != 0)
				priv->stat.tx_carrier_errors++;
			else if ((descr.Status & TXDSCR_STATUS_RTRY) != 0)
				priv->stat.tx_aborted_errors++;
		}

		/* go to next descriptor */
		priv->nexttxdone++;
		descraddr += sizeof(LANCE_TxDescr);
		if (priv->nexttxdone >= TXCOUNT) {
			priv->nexttxdone = 0;
			descraddr = RAM_TXBASE;
		}
		priv->txbusy--;
	}

	/* reset TX interrupt bit */

	SetLANCE(dev, LANCE_CSR0, oldcsr0 | CSR0_TINT);
	oldcsr0 = GetLANCE(dev, LANCE_CSR0);

	/* at least one descriptor is freed.  Therefore we can accept
	   a new one */
	/* inform upper layers we're in business again */

	netif_wake_queue(dev);

	return oldcsr0;
}

/* general interrupt entry */

static irqreturn_t irq_handler(int irq, void *device, struct pt_regs *regs)
{
	struct net_device *dev = (struct net_device *) device;
	u16 csr0val;

	/* read CSR0 to get interrupt cause */

	csr0val = GetLANCE(dev, LANCE_CSR0);

	/* in case we're not meant... */

	if ((csr0val & CSR0_INTR) == 0)
		return IRQ_NONE;

#if 0
	set_bit(LINK_STATE_RXSEM, &dev->state);
#endif

	/* loop through the interrupt bits until everything is clear */

	do {
		if ((csr0val & CSR0_IDON) != 0)
			csr0val = irqstart_handler(dev, csr0val);
		if ((csr0val & CSR0_RINT) != 0)
			csr0val = irqrx_handler(dev, csr0val);
		if ((csr0val & CSR0_MISS) != 0)
			csr0val = irqmiss_handler(dev, csr0val);
		if ((csr0val & CSR0_TINT) != 0)
			csr0val = irqtx_handler(dev, csr0val);
		if ((csr0val & CSR0_MERR) != 0) {
			SetLANCE(dev, LANCE_CSR0, csr0val | CSR0_MERR);
			csr0val = GetLANCE(dev, LANCE_CSR0);
		}
		if ((csr0val & CSR0_BABL) != 0) {
			SetLANCE(dev, LANCE_CSR0, csr0val | CSR0_BABL);
			csr0val = GetLANCE(dev, LANCE_CSR0);
		}
	}
	while ((csr0val & CSR0_INTR) != 0);

#if 0
	clear_bit(LINK_STATE_RXSEM, &dev->state);
#endif
	return IRQ_HANDLED;
}

/* ------------------------------------------------------------------------
 * driver methods
 * ------------------------------------------------------------------------ */

/* MCA info */

static int skmca_getinfo(char *buf, int slot, void *d)
{
	int len = 0, i;
	struct net_device *dev = (struct net_device *) d;
	skmca_priv *priv;

	/* can't say anything about an uninitialized device... */

	if (dev == NULL)
		return len;
	priv = netdev_priv(dev);

	/* print info */

	len += sprintf(buf + len, "IRQ: %d\n", priv->realirq);
	len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
		       dev->mem_end - 1);
	len +=
	    sprintf(buf + len, "Transceiver: %s\n",
		    MediaNames[priv->medium]);
	len += sprintf(buf + len, "Device: %s\n", dev->name);
	len += sprintf(buf + len, "MAC address:");
	for (i = 0; i < 6; i++)
		len += sprintf(buf + len, " %02x", dev->dev_addr[i]);
	buf[len++] = '\n';
	buf[len] = 0;

	return len;
}

/* open driver.  Means also initialization and start of LANCE */

static int skmca_open(struct net_device *dev)
{
	int result;
	skmca_priv *priv = netdev_priv(dev);

	/* register resources - only necessary for IRQ */
	result =
	    request_irq(priv->realirq, irq_handler,
			SA_SHIRQ | SA_SAMPLE_RANDOM, "sk_mca", dev);
	if (result != 0) {
		printk("%s: failed to register irq %d\n", dev->name,
		       dev->irq);
		return result;
	}
	dev->irq = priv->realirq;

	/* set up the card and LANCE */

	InitBoard(dev);

	/* set up flags */

	netif_start_queue(dev);

	return 0;
}

/* close driver.  Shut down board and free allocated resources */

static int skmca_close(struct net_device *dev)
{
	/* turn off board */
	DeinitBoard(dev);

	/* release resources */
	if (dev->irq != 0)
		free_irq(dev->irq, dev);
	dev->irq = 0;

	return 0;
}

/* transmit a block. */

static int skmca_tx(struct sk_buff *skb, struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);
	LANCE_TxDescr descr;
	unsigned int address;
	int tmplen, retval = 0;
	unsigned long flags;

	/* if we get called with a NULL descriptor, the Ethernet layer thinks 
	   our card is stuck an we should reset it.  We'll do this completely: */

	if (skb == NULL) {
		DeinitBoard(dev);
		InitBoard(dev);
		return 0;	/* don't try to free the block here ;-) */
	}

	/* is there space in the Tx queue ? If no, the upper layer gave us a
	   packet in spite of us not being ready and is really in trouble.
	   We'll do the dropping for him: */
	if (priv->txbusy >= TXCOUNT) {
		priv->stat.tx_dropped++;
		retval = -EIO;
		goto tx_done;
	}

	/* get TX descriptor */
	address = RAM_TXBASE + (priv->nexttxput * sizeof(LANCE_TxDescr));
	memcpy_fromio(&descr, priv->base + address, sizeof(LANCE_TxDescr));

	/* enter packet length as 2s complement - assure minimum length */
	tmplen = skb->len;
	if (tmplen < 60)
		tmplen = 60;
	descr.Len = 65536 - tmplen;

	/* copy filler into RAM - in case we're filling up... 
	   we're filling a bit more than necessary, but that doesn't harm
	   since the buffer is far larger... */
	if (tmplen > skb->len) {
		char *fill = "NetBSD is a nice OS too! ";
		unsigned int destoffs = 0, l = strlen(fill);

		while (destoffs < tmplen) {
			memcpy_toio(priv->base + descr.LowAddr +
				   destoffs, fill, l);
			destoffs += l;
		}
	}

	/* do the real data copying */
	memcpy_toio(priv->base + descr.LowAddr, skb->data, skb->len);

	/* hand descriptor over to LANCE - this is the first and last chunk */
	descr.Flags =
	    TXDSCR_FLAGS_OWN | TXDSCR_FLAGS_STP | TXDSCR_FLAGS_ENP;

#ifdef DEBUG
	PrTime();
	printk("Send packet on descr %d len %d\n", priv->nexttxput,
	       skb->len);
#endif

	/* one more descriptor busy */

	spin_lock_irqsave(&priv->lock, flags);

	priv->nexttxput++;
	if (priv->nexttxput >= TXCOUNT)
		priv->nexttxput = 0;
	priv->txbusy++;

	/* are we saturated ? */

	if (priv->txbusy >= TXCOUNT)
		netif_stop_queue(dev);

	/* write descriptor back to RAM */
	memcpy_toio(priv->base + address, &descr, sizeof(LANCE_TxDescr));

	/* if no descriptors were active, give the LANCE a hint to read it
	   immediately */

	if (priv->txbusy == 0)
		SetLANCE(dev, LANCE_CSR0, CSR0_INEA | CSR0_TDMD);

	spin_unlock_irqrestore(&priv->lock, flags);

      tx_done:

	dev_kfree_skb(skb);

	return retval;
}

/* return pointer to Ethernet statistics */

static struct net_device_stats *skmca_stats(struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);

	return &(priv->stat);
}

/* switch receiver mode.  We use the LANCE's multicast filter to prefilter
   multicast addresses. */

static void skmca_set_multicast_list(struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);
	LANCE_InitBlock block;

	/* first stop the LANCE... */
	StopLANCE(dev);

	/* ...then modify the initialization block... */
	memcpy_fromio(&block, priv->base + RAM_INITBASE, sizeof(block));
	if (dev->flags & IFF_PROMISC)
		block.Mode |= LANCE_INIT_PROM;
	else
		block.Mode &= ~LANCE_INIT_PROM;

	if (dev->flags & IFF_ALLMULTI) {	/* get all multicasts */
		memset(block.LAdrF, 0xff, sizeof(block.LAdrF));
	} else {		/* get selected/no multicasts */

		struct dev_mc_list *mptr;
		int code;

		memset(block.LAdrF, 0, sizeof(block.LAdrF));
		for (mptr = dev->mc_list; mptr != NULL; mptr = mptr->next) {
			code = GetHash(mptr->dmi_addr);
			block.LAdrF[(code >> 3) & 7] |= 1 << (code & 7);
		}
	}

	memcpy_toio(priv->base + RAM_INITBASE, &block, sizeof(block));

	/* ...then reinit LANCE with the correct flags */
	InitLANCE(dev);
}

/* ------------------------------------------------------------------------
 * hardware check
 * ------------------------------------------------------------------------ */

static int startslot;		/* counts through slots when probing multiple devices */

static void cleanup_card(struct net_device *dev)
{
	skmca_priv *priv = netdev_priv(dev);
	DeinitBoard(dev);
	if (dev->irq != 0)
		free_irq(dev->irq, dev);
	iounmap(priv->base);
	mca_mark_as_unused(priv->slot);
	mca_set_adapter_procfn(priv->slot, NULL, NULL);
}

struct net_device * __init skmca_probe(int unit)
{
	struct net_device *dev;
	int force_detect = 0;
	int junior, slot, i;
	int base = 0, irq = 0;
	skmca_priv *priv;
	skmca_medium medium;
	int err;

	/* can't work without an MCA bus ;-) */

	if (MCA_bus == 0)
		return ERR_PTR(-ENODEV);

	dev = alloc_etherdev(sizeof(skmca_priv));
	if (!dev)
		return ERR_PTR(-ENOMEM);

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

	SET_MODULE_OWNER(dev);

	/* start address of 1 --> forced detection */

	if (dev->mem_start == 1)
		force_detect = 1;

	/* search through slots */

	base = dev->mem_start;
	irq = dev->base_addr;
	for (slot = startslot; (slot = dofind(&junior, slot)) != -1; slot++) {
		/* deduce card addresses */

		getaddrs(slot, junior, &base, &irq, &medium);

		/* slot already in use ? */

		if (mca_is_adapter_used(slot))
			continue;

		/* were we looking for something different ? */

		if (dev->irq && dev->irq != irq)
			continue;
		if (dev->mem_start && dev->mem_start != base)
			continue;

		/* found something that matches */

		break;
	}

	/* nothing found ? */

	if (slot == -1) {
		free_netdev(dev);
		return (base || irq) ? ERR_PTR(-ENXIO) : ERR_PTR(-ENODEV);
	}

	/* make procfs entries */

	if (junior)
		mca_set_adapter_name(slot,
				     "SKNET junior MC2 Ethernet Adapter");
	else
		mca_set_adapter_name(slot, "SKNET MC2+ Ethernet Adapter");
	mca_set_adapter_procfn(slot, (MCA_ProcFn) skmca_getinfo, dev);

	mca_mark_as_used(slot);

	/* announce success */
	printk("%s: SKNet %s adapter found in slot %d\n", dev->name,
	       junior ? "Junior MC2" : "MC2+", slot + 1);

	priv = netdev_priv(dev);
	priv->base = ioremap(base, 0x4000);
	if (!priv->base) {
		mca_set_adapter_procfn(slot, NULL, NULL);
		mca_mark_as_unused(slot);
		free_netdev(dev);
		return ERR_PTR(-ENOMEM);
	}

	priv->slot = slot;
	priv->macbase = priv->base + 0x3fc0;
	priv->ioregaddr = priv->base + 0x3ff0;
	priv->ctrladdr = priv->base + 0x3ff2;
	priv->cmdaddr = priv->base + 0x3ff3;
	priv->medium = medium;
	memset(&priv->stat, 0, sizeof(struct net_device_stats));
	spin_lock_init(&priv->lock);

	/* set base + irq for this device (irq not allocated so far) */
	dev->irq = 0;
	dev->mem_start = base;
	dev->mem_end = base + 0x4000;

	/* autoprobe ? */
	if (irq < 0) {
		int nirq;

		printk
		    ("%s: ambigous POS bit combination, must probe for IRQ...\n",
		     dev->name);
		nirq = ProbeIRQ(dev);
		if (nirq <= 0)
			printk("%s: IRQ probe failed, assuming IRQ %d",
			       dev->name, priv->realirq = -irq);
		else
			priv->realirq = nirq;
	} else
		priv->realirq = irq;

	/* set methods */
	dev->open = skmca_open;
	dev->stop = skmca_close;
	dev->hard_start_xmit = skmca_tx;
	dev->do_ioctl = NULL;
	dev->get_stats = skmca_stats;
	dev->set_multicast_list = skmca_set_multicast_list;
	dev->flags |= IFF_MULTICAST;

	/* copy out MAC address */
	for (i = 0; i < 6; i++)
		dev->dev_addr[i] = readb(priv->macbase + (i << 1));

	/* print config */
	printk("%s: IRQ %d, memory %#lx-%#lx, "
	       "MAC address %02x:%02x:%02x:%02x:%02x:%02x.\n",
	       dev->name, priv->realirq, dev->mem_start, dev->mem_end - 1,
	       dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
	       dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
	printk("%s: %s medium\n", dev->name, MediaNames[priv->medium]);

	/* reset board */

	ResetBoard(dev);

	startslot = slot + 1;

	err = register_netdev(dev);
	if (err) {
		cleanup_card(dev);
		free_netdev(dev);
		dev = ERR_PTR(err);
	}
	return dev;
}

/* ------------------------------------------------------------------------
 * modularization support
 * ------------------------------------------------------------------------ */

#ifdef MODULE
MODULE_LICENSE("GPL");

#define DEVMAX 5

static struct net_device *moddevs[DEVMAX];

int init_module(void)
{
	int z;

	startslot = 0;
	for (z = 0; z < DEVMAX; z++) {
		struct net_device *dev = skmca_probe(-1);
		if (IS_ERR(dev))
			break;
		moddevs[z] = dev;
	}
	if (!z)
		return -EIO;
	return 0;
}

void cleanup_module(void)
{
	int z;

	for (z = 0; z < DEVMAX; z++) {
		struct net_device *dev = moddevs[z];
		if (dev) {
			unregister_netdev(dev);
			cleanup_card(dev);
			free_netdev(dev);
		}
	}
}
#endif				/* MODULE */
