/* wd.c: A WD80x3 ethernet driver for linux. */
/*
	Written 1993-94 by Donald Becker.

	Copyright 1993 United States Government as represented by the
	Director, National Security Agency.

	This software may be used and distributed according to the terms
	of the GNU General Public License, incorporated herein by reference.

	The author may be reached as becker@scyld.com, or C/O
	Scyld Computing Corporation
	410 Severn Ave., Suite 210
	Annapolis MD 21403

	This is a driver for WD8003 and WD8013 "compatible" ethercards.

	Thanks to Russ Nelson (nelson@crnwyr.com) for loaning me a WD8013.

	Changelog:

	Paul Gortmaker	: multiple card support for module users, support
			  for non-standard memory sizes.


*/

static const char version[] =
	"wd.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>

#include <asm/io.h>

#include "8390.h"

#define DRV_NAME "wd"

/* A zero-terminated list of I/O addresses to be probed. */
static unsigned int wd_portlist[] __initdata =
{0x300, 0x280, 0x380, 0x240, 0};

static int wd_probe1(struct net_device *dev, int ioaddr);

static int wd_open(struct net_device *dev);
static void wd_reset_8390(struct net_device *dev);
static void wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr,
						int ring_page);
static void wd_block_input(struct net_device *dev, int count,
						  struct sk_buff *skb, int ring_offset);
static void wd_block_output(struct net_device *dev, int count,
							const unsigned char *buf, int start_page);
static int wd_close(struct net_device *dev);


#define WD_START_PG		0x00	/* First page of TX buffer */
#define WD03_STOP_PG	0x20	/* Last page +1 of RX ring */
#define WD13_STOP_PG	0x40	/* Last page +1 of RX ring */

#define WD_CMDREG		0		/* Offset to ASIC command register. */
#define	 WD_RESET		0x80	/* Board reset, in WD_CMDREG. */
#define	 WD_MEMENB		0x40	/* Enable the shared memory. */
#define WD_CMDREG5		5		/* Offset to 16-bit-only ASIC register 5. */
#define	 ISA16			0x80	/* Enable 16 bit access from the ISA bus. */
#define	 NIC16			0x40	/* Enable 16 bit access from the 8390. */
#define WD_NIC_OFFSET	16		/* Offset to the 8390 from the base_addr. */
#define WD_IO_EXTENT	32


/*	Probe for the WD8003 and WD8013.  These cards have the station
	address PROM at I/O ports <base>+8 to <base>+13, with a checksum
	following. A Soundblaster can have the same checksum as an WDethercard,
	so we have an extra exclusionary check for it.

	The wd_probe1() routine initializes the card and fills the
	station address field. */

static int __init do_wd_probe(struct net_device *dev)
{
	int i;
	struct resource *r;
	int base_addr = dev->base_addr;
	int irq = dev->irq;
	int mem_start = dev->mem_start;
	int mem_end = dev->mem_end;

	if (base_addr > 0x1ff) {	/* Check a user specified location. */
		r = request_region(base_addr, WD_IO_EXTENT, "wd-probe");
		if ( r == NULL)
			return -EBUSY;
		i = wd_probe1(dev, base_addr);
		if (i != 0)
			release_region(base_addr, WD_IO_EXTENT);
		else
			r->name = dev->name;
		return i;
	}
	else if (base_addr != 0)	/* Don't probe at all. */
		return -ENXIO;

	for (i = 0; wd_portlist[i]; i++) {
		int ioaddr = wd_portlist[i];
		r = request_region(ioaddr, WD_IO_EXTENT, "wd-probe");
		if (r == NULL)
			continue;
		if (wd_probe1(dev, ioaddr) == 0) {
			r->name = dev->name;
			return 0;
		}
		release_region(ioaddr, WD_IO_EXTENT);
		dev->irq = irq;
		dev->mem_start = mem_start;
		dev->mem_end = mem_end;
	}

	return -ENODEV;
}

#ifndef MODULE
struct net_device * __init wd_probe(int unit)
{
	struct net_device *dev = alloc_ei_netdev();
	int err;

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

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

	err = do_wd_probe(dev);
	if (err)
		goto out;
	return dev;
out:
	free_netdev(dev);
	return ERR_PTR(err);
}
#endif

static const struct net_device_ops wd_netdev_ops = {
	.ndo_open		= wd_open,
	.ndo_stop		= wd_close,
	.ndo_start_xmit		= ei_start_xmit,
	.ndo_tx_timeout		= ei_tx_timeout,
	.ndo_get_stats		= ei_get_stats,
	.ndo_set_rx_mode	= ei_set_multicast_list,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address 	= eth_mac_addr,
	.ndo_change_mtu		= eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller 	= ei_poll,
#endif
};

static int __init wd_probe1(struct net_device *dev, int ioaddr)
{
	int i;
	int err;
	int checksum = 0;
	int ancient = 0;			/* An old card without config registers. */
	int word16 = 0;				/* 0 = 8 bit, 1 = 16 bit */
	const char *model_name;
	static unsigned version_printed;

	for (i = 0; i < 8; i++)
		checksum += inb(ioaddr + 8 + i);
	if (inb(ioaddr + 8) == 0xff 	/* Extra check to avoid soundcard. */
		|| inb(ioaddr + 9) == 0xff
		|| (checksum & 0xff) != 0xFF)
		return -ENODEV;

	/* Check for semi-valid mem_start/end values if supplied. */
	if ((dev->mem_start % 0x2000) || (dev->mem_end % 0x2000)) {
		printk(KERN_WARNING "wd.c: user supplied mem_start or mem_end not on 8kB boundary - ignored.\n");
		dev->mem_start = 0;
		dev->mem_end = 0;
	}

	if (ei_debug  &&  version_printed++ == 0)
		printk(version);

	for (i = 0; i < 6; i++)
		dev->dev_addr[i] = inb(ioaddr + 8 + i);

	printk("%s: WD80x3 at %#3x, %pM",
	       dev->name, ioaddr, dev->dev_addr);

	/* The following PureData probe code was contributed by
	   Mike Jagdis <jaggy@purplet.demon.co.uk>. Puredata does software
	   configuration differently from others so we have to check for them.
	   This detects an 8 bit, 16 bit or dumb (Toshiba, jumpered) card.
	   */
	if (inb(ioaddr+0) == 'P' && inb(ioaddr+1) == 'D') {
		unsigned char reg5 = inb(ioaddr+5);

		switch (inb(ioaddr+2)) {
		case 0x03: word16 = 0; model_name = "PDI8023-8";	break;
		case 0x05: word16 = 0; model_name = "PDUC8023";	break;
		case 0x0a: word16 = 1; model_name = "PDI8023-16"; break;
			/* Either 0x01 (dumb) or they've released a new version. */
		default:	 word16 = 0; model_name = "PDI8023";	break;
		}
		dev->mem_start = ((reg5 & 0x1c) + 0xc0) << 12;
		dev->irq = (reg5 & 0xe0) == 0xe0 ? 10 : (reg5 >> 5) + 1;
	} else {								/* End of PureData probe */
		/* This method of checking for a 16-bit board is borrowed from the
		   we.c driver.  A simpler method is just to look in ASIC reg. 0x03.
		   I'm comparing the two method in alpha test to make certain they
		   return the same result. */
		/* Check for the old 8 bit board - it has register 0/8 aliasing.
		   Do NOT check i>=6 here -- it hangs the old 8003 boards! */
		for (i = 0; i < 6; i++)
			if (inb(ioaddr+i) != inb(ioaddr+8+i))
				break;
		if (i >= 6) {
			ancient = 1;
			model_name = "WD8003-old";
			word16 = 0;
		} else {
			int tmp = inb(ioaddr+1); /* fiddle with 16bit bit */
			outb( tmp ^ 0x01, ioaddr+1 ); /* attempt to clear 16bit bit */
			if (((inb( ioaddr+1) & 0x01) == 0x01) /* A 16 bit card */
				&& (tmp & 0x01) == 0x01	) {				/* In a 16 slot. */
				int asic_reg5 = inb(ioaddr+WD_CMDREG5);
				/* Magic to set ASIC to word-wide mode. */
				outb( NIC16 | (asic_reg5&0x1f), ioaddr+WD_CMDREG5);
				outb(tmp, ioaddr+1);
				model_name = "WD8013";
				word16 = 1;		/* We have a 16bit board here! */
			} else {
				model_name = "WD8003";
				word16 = 0;
			}
			outb(tmp, ioaddr+1);			/* Restore original reg1 value. */
		}
#ifndef final_version
		if ( !ancient && (inb(ioaddr+1) & 0x01) != (word16 & 0x01))
			printk("\nWD80?3: Bus width conflict, %d (probe) != %d (reg report).",
				   word16 ? 16 : 8, (inb(ioaddr+1) & 0x01) ? 16 : 8);
#endif
	}

#if defined(WD_SHMEM) && WD_SHMEM > 0x80000
	/* Allow a compile-time override.	 */
	dev->mem_start = WD_SHMEM;
#else
	if (dev->mem_start == 0) {
		/* Sanity and old 8003 check */
		int reg0 = inb(ioaddr);
		if (reg0 == 0xff || reg0 == 0) {
			/* Future plan: this could check a few likely locations first. */
			dev->mem_start = 0xd0000;
			printk(" assigning address %#lx", dev->mem_start);
		} else {
			int high_addr_bits = inb(ioaddr+WD_CMDREG5) & 0x1f;
			/* Some boards don't have the register 5 -- it returns 0xff. */
			if (high_addr_bits == 0x1f || word16 == 0)
				high_addr_bits = 0x01;
			dev->mem_start = ((reg0&0x3f) << 13) + (high_addr_bits << 19);
		}
	}
#endif

	/* The 8390 isn't at the base address -- the ASIC regs are there! */
	dev->base_addr = ioaddr+WD_NIC_OFFSET;

	if (dev->irq < 2) {
		static const int irqmap[] = {9, 3, 5, 7, 10, 11, 15, 4};
		int reg1 = inb(ioaddr+1);
		int reg4 = inb(ioaddr+4);
		if (ancient || reg1 == 0xff) {	/* Ack!! No way to read the IRQ! */
			short nic_addr = ioaddr+WD_NIC_OFFSET;
			unsigned long irq_mask;

			/* We have an old-style ethercard that doesn't report its IRQ
			   line.  Do autoirq to find the IRQ line. Note that this IS NOT
			   a reliable way to trigger an interrupt. */
			outb_p(E8390_NODMA + E8390_STOP, nic_addr);
			outb(0x00, nic_addr+EN0_IMR);	/* Disable all intrs. */

			irq_mask = probe_irq_on();
			outb_p(0xff, nic_addr + EN0_IMR);	/* Enable all interrupts. */
			outb_p(0x00, nic_addr + EN0_RCNTLO);
			outb_p(0x00, nic_addr + EN0_RCNTHI);
			outb(E8390_RREAD+E8390_START, nic_addr); /* Trigger it... */
			mdelay(20);
			dev->irq = probe_irq_off(irq_mask);

			outb_p(0x00, nic_addr+EN0_IMR);	/* Mask all intrs. again. */

			if (ei_debug > 2)
				printk(" autoirq is %d", dev->irq);
			if (dev->irq < 2)
				dev->irq = word16 ? 10 : 5;
		} else
			dev->irq = irqmap[((reg4 >> 5) & 0x03) + (reg1 & 0x04)];
	} else if (dev->irq == 2)		/* Fixup bogosity: IRQ2 is really IRQ9 */
		dev->irq = 9;

	/* Snarf the interrupt now.  There's no point in waiting since we cannot
	   share and the board will usually be enabled. */
	i = request_irq(dev->irq, ei_interrupt, 0, DRV_NAME, dev);
	if (i) {
		printk (" unable to get IRQ %d.\n", dev->irq);
		return i;
	}

	/* OK, were are certain this is going to work.  Setup the device. */
	ei_status.name = model_name;
	ei_status.word16 = word16;
	ei_status.tx_start_page = WD_START_PG;
	ei_status.rx_start_page = WD_START_PG + TX_PAGES;

	/* Don't map in the shared memory until the board is actually opened. */

	/* Some cards (eg WD8003EBT) can be jumpered for more (32k!) memory. */
	if (dev->mem_end != 0) {
		ei_status.stop_page = (dev->mem_end - dev->mem_start)/256;
		ei_status.priv = dev->mem_end - dev->mem_start;
	} else {
		ei_status.stop_page = word16 ? WD13_STOP_PG : WD03_STOP_PG;
		dev->mem_end = dev->mem_start + (ei_status.stop_page - WD_START_PG)*256;
		ei_status.priv = (ei_status.stop_page - WD_START_PG)*256;
	}

	ei_status.mem = ioremap(dev->mem_start, ei_status.priv);
	if (!ei_status.mem) {
		free_irq(dev->irq, dev);
		return -ENOMEM;
	}

	printk(" %s, IRQ %d, shared memory at %#lx-%#lx.\n",
		   model_name, dev->irq, dev->mem_start, dev->mem_end-1);

	ei_status.reset_8390 = wd_reset_8390;
	ei_status.block_input = wd_block_input;
	ei_status.block_output = wd_block_output;
	ei_status.get_8390_hdr = wd_get_8390_hdr;

	dev->netdev_ops = &wd_netdev_ops;
	NS8390_init(dev, 0);

#if 1
	/* Enable interrupt generation on softconfig cards -- M.U */
	/* .. but possibly potentially unsafe - Donald */
	if (inb(ioaddr+14) & 0x20)
		outb(inb(ioaddr+4)|0x80, ioaddr+4);
#endif

	err = register_netdev(dev);
	if (err) {
		free_irq(dev->irq, dev);
		iounmap(ei_status.mem);
	}
	return err;
}

static int
wd_open(struct net_device *dev)
{
  int ioaddr = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */

  /* Map in the shared memory. Always set register 0 last to remain
	 compatible with very old boards. */
  ei_status.reg0 = ((dev->mem_start>>13) & 0x3f) | WD_MEMENB;
  ei_status.reg5 = ((dev->mem_start>>19) & 0x1f) | NIC16;

  if (ei_status.word16)
	  outb(ei_status.reg5, ioaddr+WD_CMDREG5);
  outb(ei_status.reg0, ioaddr); /* WD_CMDREG */

  return ei_open(dev);
}

static void
wd_reset_8390(struct net_device *dev)
{
	int wd_cmd_port = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */

	outb(WD_RESET, wd_cmd_port);
	if (ei_debug > 1) printk("resetting the WD80x3 t=%lu...", jiffies);
	ei_status.txing = 0;

	/* Set up the ASIC registers, just in case something changed them. */
	outb((((dev->mem_start>>13) & 0x3f)|WD_MEMENB), wd_cmd_port);
	if (ei_status.word16)
		outb(NIC16 | ((dev->mem_start>>19) & 0x1f), wd_cmd_port+WD_CMDREG5);

	if (ei_debug > 1) printk("reset done\n");
}

/* Grab the 8390 specific header. Similar to the block_input routine, but
   we don't need to be concerned with ring wrap as the header will be at
   the start of a page, so we optimize accordingly. */

static void
wd_get_8390_hdr(struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
{

	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
	void __iomem *hdr_start = ei_status.mem + ((ring_page - WD_START_PG)<<8);

	/* We'll always get a 4 byte header read followed by a packet read, so
	   we enable 16 bit mode before the header, and disable after the body. */
	if (ei_status.word16)
		outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);

#ifdef __BIG_ENDIAN
	/* Officially this is what we are doing, but the readl() is faster */
	/* unfortunately it isn't endian aware of the struct               */
	memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
	hdr->count = le16_to_cpu(hdr->count);
#else
	((unsigned int*)hdr)[0] = readl(hdr_start);
#endif
}

/* Block input and output are easy on shared memory ethercards, and trivial
   on the Western digital card where there is no choice of how to do it.
   The only complications are that the ring buffer wraps, and need to map
   switch between 8- and 16-bit modes. */

static void
wd_block_input(struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
{
	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
	unsigned long offset = ring_offset - (WD_START_PG<<8);
	void __iomem *xfer_start = ei_status.mem + offset;

	if (offset + count > ei_status.priv) {
		/* We must wrap the input move. */
		int semi_count = ei_status.priv - offset;
		memcpy_fromio(skb->data, xfer_start, semi_count);
		count -= semi_count;
		memcpy_fromio(skb->data + semi_count, ei_status.mem + TX_PAGES * 256, count);
	} else {
		/* Packet is in one chunk -- we can copy + cksum. */
		memcpy_fromio(skb->data, xfer_start, count);
	}

	/* Turn off 16 bit access so that reboot works.	 ISA brain-damage */
	if (ei_status.word16)
		outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
}

static void
wd_block_output(struct net_device *dev, int count, const unsigned char *buf,
				int start_page)
{
	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */
	void __iomem *shmem = ei_status.mem + ((start_page - WD_START_PG)<<8);


	if (ei_status.word16) {
		/* Turn on and off 16 bit access so that reboot works. */
		outb(ISA16 | ei_status.reg5, wd_cmdreg+WD_CMDREG5);
		memcpy_toio(shmem, buf, count);
		outb(ei_status.reg5, wd_cmdreg+WD_CMDREG5);
	} else
		memcpy_toio(shmem, buf, count);
}


static int
wd_close(struct net_device *dev)
{
	int wd_cmdreg = dev->base_addr - WD_NIC_OFFSET; /* WD_CMDREG */

	if (ei_debug > 1)
		printk("%s: Shutting down ethercard.\n", dev->name);
	ei_close(dev);

	/* Change from 16-bit to 8-bit shared memory so reboot works. */
	if (ei_status.word16)
		outb(ei_status.reg5, wd_cmdreg + WD_CMDREG5 );

	/* And disable the shared memory. */
	outb(ei_status.reg0 & ~WD_MEMENB, wd_cmdreg);

	return 0;
}


#ifdef MODULE
#define MAX_WD_CARDS	4	/* Max number of wd cards per module */
static struct net_device *dev_wd[MAX_WD_CARDS];
static int io[MAX_WD_CARDS];
static int irq[MAX_WD_CARDS];
static int mem[MAX_WD_CARDS];
static int mem_end[MAX_WD_CARDS];	/* for non std. mem size */

module_param_array(io, int, NULL, 0);
module_param_array(irq, int, NULL, 0);
module_param_array(mem, int, NULL, 0);
module_param_array(mem_end, int, NULL, 0);
MODULE_PARM_DESC(io, "I/O base address(es)");
MODULE_PARM_DESC(irq, "IRQ number(s) (ignored for PureData boards)");
MODULE_PARM_DESC(mem, "memory base address(es)(ignored for PureData boards)");
MODULE_PARM_DESC(mem_end, "memory end address(es)");
MODULE_DESCRIPTION("ISA Western Digital wd8003/wd8013 ; SMC Elite, Elite16 ethernet driver");
MODULE_LICENSE("GPL");

/* This is set up so that only a single autoprobe takes place per call.
ISA device autoprobes on a running machine are not recommended. */

int __init init_module(void)
{
	struct net_device *dev;
	int this_dev, found = 0;

	for (this_dev = 0; this_dev < MAX_WD_CARDS; this_dev++) {
		if (io[this_dev] == 0)  {
			if (this_dev != 0) break; /* only autoprobe 1st one */
			printk(KERN_NOTICE "wd.c: Presently autoprobing (not recommended) for a single card.\n");
		}
		dev = alloc_ei_netdev();
		if (!dev)
			break;
		dev->irq = irq[this_dev];
		dev->base_addr = io[this_dev];
		dev->mem_start = mem[this_dev];
		dev->mem_end = mem_end[this_dev];
		if (do_wd_probe(dev) == 0) {
			dev_wd[found++] = dev;
			continue;
		}
		free_netdev(dev);
		printk(KERN_WARNING "wd.c: No wd80x3 card found (i/o = 0x%x).\n", io[this_dev]);
		break;
	}
	if (found)
		return 0;
	return -ENXIO;
}

static void cleanup_card(struct net_device *dev)
{
	free_irq(dev->irq, dev);
	release_region(dev->base_addr - WD_NIC_OFFSET, WD_IO_EXTENT);
	iounmap(ei_status.mem);
}

void __exit
cleanup_module(void)
{
	int this_dev;

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