/* 
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)
{
	int z;

	for (z = 0; z < len; z++) {
		if ((z & 15) == 0)
			printk("%04x:", z);
		printk(" %02x", SKMCA_READB(dev->mem_start + 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 = (skmca_priv *) dev->priv;

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

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

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

	while ((SKMCA_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 = (skmca_priv *) dev->priv;
	unsigned long flags;

	/* disable interrupts */

	spin_lock_irqsave(&priv->lock, flags);

	/* wait until no transfer is pending */

	WaitLANCE(dev);

	/* transfer register address to RAP */

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

	/* transfer data to register */

	SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_WRITE | CTRL_ADR_DATA,
		     priv->ctrladdr);
	SKMCA_WRITEW(value, priv->ioregaddr);
	SKMCA_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 = (skmca_priv *) dev->priv;
	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 */

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

	/* transfer data from register */

	SKMCA_WRITEB(CTRL_RESET_OFF | CTRL_RW_READ | CTRL_ADR_DATA,
		     priv->ctrladdr);
	SKMCA_WRITEB(IOCMD_GO, priv->cmdaddr);
	udelay(1);
	WaitLANCE(dev);
	res = SKMCA_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)
{
	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;
			SKMCA_TOIO(dev->mem_start + RAM_TXBASE +
				   (z * sizeof(LANCE_TxDescr)), &descr,
				   sizeof(LANCE_TxDescr));
			SKMCA_SETIO(dev->mem_start + 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;
			SKMCA_TOIO(dev->mem_start + RAM_RXBASE +
				   (z * sizeof(LANCE_RxDescr)), &descr,
				   sizeof(LANCE_RxDescr));
			SKMCA_SETIO(dev->mem_start + 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 = (skmca_priv *) dev->priv;

	/* 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)
{
	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);

	SKMCA_TOIO(dev->mem_start + 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 = (skmca_priv *) dev->priv;

	/* 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 = (skmca_priv *) dev->priv;
	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 */
		SKMCA_FROMIO(&descr, dev->mem_start + 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 {
				SKMCA_FROMIO(skb_put(skb, descr.Len),
					     dev->mem_start +
					     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 */
		SKMCA_TOIO(dev->mem_start + 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 = (skmca_priv *) dev->priv;
	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 */
		SKMCA_FROMIO(&descr, dev->mem_start + 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;
	if (dev->priv == NULL)
		return len;
	priv = (skmca_priv *) dev->priv;

	/* 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 = (skmca_priv *) dev->priv;

	/* 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 = (skmca_priv *) dev->priv;
	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));
	SKMCA_FROMIO(&descr, dev->mem_start + 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) {
			SKMCA_TOIO(dev->mem_start + descr.LowAddr +
				   destoffs, fill, l);
			destoffs += l;
		}
	}

	/* do the real data copying */
	SKMCA_TOIO(dev->mem_start + 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 */
	SKMCA_TOIO(dev->mem_start + 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 = (skmca_priv *) dev->priv;

	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)
{
	LANCE_InitBlock block;

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

	/* ...then modify the initialization block... */
	SKMCA_FROMIO(&block, dev->mem_start + 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);
		}
	}

	SKMCA_TOIO(dev->mem_start + 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 = dev->priv;
	DeinitBoard(dev);
	if (dev->irq != 0)
		free_irq(dev->irq, dev);
	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);

	/* allocate structure */
	priv = dev->priv;
	priv->slot = slot;
	priv->macbase = base + 0x3fc0;
	priv->ioregaddr = base + 0x3ff0;
	priv->ctrladdr = base + 0x3ff2;
	priv->cmdaddr = 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] = SKMCA_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 */
