/*
 * Linux ARCnet driver - COM90xx chipset (memory-mapped buffers)
 * 
 * Written 1994-1999 by Avery Pennarun.
 * Written 1999 by Martin Mares <mj@ucw.cz>.
 * Derived from skeleton.c by Donald Becker.
 *
 * Special thanks to Contemporary Controls, Inc. (www.ccontrols.com)
 *  for sponsoring the further development of this driver.
 *
 * **********************
 *
 * The original copyright of skeleton.c was as follows:
 *
 * skeleton.c Written 1993 by Donald Becker.
 * Copyright 1993 United States Government as represented by the
 * Director, National Security Agency.  This software may only be used
 * and distributed according to the terms of the GNU General Public License as
 * modified by SRC, incorporated herein by reference.
 *
 * **********************
 *
 * For more details, see drivers/net/arcnet.c
 *
 * **********************
 */
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/slab.h>
#include <asm/io.h>
#include <linux/arcdevice.h>


#define VERSION "arcnet: COM90xx chipset support\n"


/* Define this to speed up the autoprobe by assuming if only one io port and
 * shmem are left in the list at Stage 5, they must correspond to each
 * other.
 *
 * This is undefined by default because it might not always be true, and the
 * extra check makes the autoprobe even more careful.  Speed demons can turn
 * it on - I think it should be fine if you only have one ARCnet card
 * installed.
 *
 * If no ARCnet cards are installed, this delay never happens anyway and thus
 * the option has no effect.
 */
#undef FAST_PROBE


/* Internal function declarations */
static int com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *);
static void com90xx_command(struct net_device *dev, int command);
static int com90xx_status(struct net_device *dev);
static void com90xx_setmask(struct net_device *dev, int mask);
static int com90xx_reset(struct net_device *dev, int really_reset);
static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
				 void *buf, int count);
static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
				   void *buf, int count);

/* Known ARCnet cards */

static struct net_device *cards[16];
static int numcards;

/* Handy defines for ARCnet specific stuff */

/* The number of low I/O ports used by the card */
#define ARCNET_TOTAL_SIZE	16

/* Amount of I/O memory used by the card */
#define BUFFER_SIZE (512)
#define MIRROR_SIZE (BUFFER_SIZE*4)

/* COM 9026 controller chip --> ARCnet register addresses */
#define _INTMASK (ioaddr+0)	/* writable */
#define _STATUS  (ioaddr+0)	/* readable */
#define _COMMAND (ioaddr+1)	/* writable, returns random vals on read (?) */
#define _CONFIG  (ioaddr+2)	/* Configuration register */
#define _RESET   (ioaddr+8)	/* software reset (on read) */
#define _MEMDATA (ioaddr+12)	/* Data port for IO-mapped memory */
#define _ADDR_HI (ioaddr+15)	/* Control registers for said */
#define _ADDR_LO (ioaddr+14)

#undef ASTATUS
#undef ACOMMAND
#undef AINTMASK

#define ASTATUS()	inb(_STATUS)
#define ACOMMAND(cmd) 	outb((cmd),_COMMAND)
#define AINTMASK(msk)	outb((msk),_INTMASK)


static int com90xx_skip_probe __initdata = 0;

/* Module parameters */

static int io;			/* use the insmod io= irq= shmem= options */
static int irq;
static int shmem;
static char device[9];		/* use eg. device=arc1 to change name */

module_param(io, int, 0);
module_param(irq, int, 0);
module_param(shmem, int, 0);
module_param_string(device, device, sizeof(device), 0);

static void __init com90xx_probe(void)
{
	int count, status, ioaddr, numprint, airq, openparen = 0;
	unsigned long airqmask;
	int ports[(0x3f0 - 0x200) / 16 + 1] =
	{0};
	unsigned long *shmems;
	void __iomem **iomem;
	int numports, numshmems, *port;
	u_long *p;
	int index;

	if (!io && !irq && !shmem && !*device && com90xx_skip_probe)
		return;

	shmems = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(unsigned long),
			 GFP_KERNEL);
	if (!shmems)
		return;
	iomem = kzalloc(((0x100000-0xa0000) / 0x800) * sizeof(void __iomem *),
			 GFP_KERNEL);
	if (!iomem) {
		kfree(shmems);
		return;
	}

	BUGLVL(D_NORMAL) printk(VERSION);

	/* set up the arrays where we'll store the possible probe addresses */
	numports = numshmems = 0;
	if (io)
		ports[numports++] = io;
	else
		for (count = 0x200; count <= 0x3f0; count += 16)
			ports[numports++] = count;
	if (shmem)
		shmems[numshmems++] = shmem;
	else
		for (count = 0xA0000; count <= 0xFF800; count += 2048)
			shmems[numshmems++] = count;

	/* Stage 1: abandon any reserved ports, or ones with status==0xFF
	 * (empty), and reset any others by reading the reset port.
	 */
	numprint = -1;
	for (port = &ports[0]; port - ports < numports; port++) {
		numprint++;
		numprint %= 8;
		if (!numprint) {
			BUGMSG2(D_INIT, "\n");
			BUGMSG2(D_INIT, "S1: ");
		}
		BUGMSG2(D_INIT, "%Xh ", *port);

		ioaddr = *port;

		if (!request_region(*port, ARCNET_TOTAL_SIZE, "arcnet (90xx)")) {
			BUGMSG2(D_INIT_REASONS, "(request_region)\n");
			BUGMSG2(D_INIT_REASONS, "S1: ");
			BUGLVL(D_INIT_REASONS) numprint = 0;
			*port-- = ports[--numports];
			continue;
		}
		if (ASTATUS() == 0xFF) {
			BUGMSG2(D_INIT_REASONS, "(empty)\n");
			BUGMSG2(D_INIT_REASONS, "S1: ");
			BUGLVL(D_INIT_REASONS) numprint = 0;
			release_region(*port, ARCNET_TOTAL_SIZE);
			*port-- = ports[--numports];
			continue;
		}
		inb(_RESET);	/* begin resetting card */

		BUGMSG2(D_INIT_REASONS, "\n");
		BUGMSG2(D_INIT_REASONS, "S1: ");
		BUGLVL(D_INIT_REASONS) numprint = 0;
	}
	BUGMSG2(D_INIT, "\n");

	if (!numports) {
		BUGMSG2(D_NORMAL, "S1: No ARCnet cards found.\n");
		kfree(shmems);
		kfree(iomem);
		return;
	}
	/* Stage 2: we have now reset any possible ARCnet cards, so we can't
	 * do anything until they finish.  If D_INIT, print the list of
	 * cards that are left.
	 */
	numprint = -1;
	for (port = &ports[0]; port < ports + numports; port++) {
		numprint++;
		numprint %= 8;
		if (!numprint) {
			BUGMSG2(D_INIT, "\n");
			BUGMSG2(D_INIT, "S2: ");
		}
		BUGMSG2(D_INIT, "%Xh ", *port);
	}
	BUGMSG2(D_INIT, "\n");
	mdelay(RESETtime);

	/* Stage 3: abandon any shmem addresses that don't have the signature
	 * 0xD1 byte in the right place, or are read-only.
	 */
	numprint = -1;
	for (index = 0, p = &shmems[0]; index < numshmems; p++, index++) {
		void __iomem *base;

		numprint++;
		numprint %= 8;
		if (!numprint) {
			BUGMSG2(D_INIT, "\n");
			BUGMSG2(D_INIT, "S3: ");
		}
		BUGMSG2(D_INIT, "%lXh ", *p);

		if (!request_mem_region(*p, MIRROR_SIZE, "arcnet (90xx)")) {
			BUGMSG2(D_INIT_REASONS, "(request_mem_region)\n");
			BUGMSG2(D_INIT_REASONS, "Stage 3: ");
			BUGLVL(D_INIT_REASONS) numprint = 0;
			goto out;
		}
		base = ioremap(*p, MIRROR_SIZE);
		if (!base) {
			BUGMSG2(D_INIT_REASONS, "(ioremap)\n");
			BUGMSG2(D_INIT_REASONS, "Stage 3: ");
			BUGLVL(D_INIT_REASONS) numprint = 0;
			goto out1;
		}
		if (readb(base) != TESTvalue) {
			BUGMSG2(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
				readb(base), TESTvalue);
			BUGMSG2(D_INIT_REASONS, "S3: ");
			BUGLVL(D_INIT_REASONS) numprint = 0;
			goto out2;
		}
		/* By writing 0x42 to the TESTvalue location, we also make
		 * sure no "mirror" shmem areas show up - if they occur
		 * in another pass through this loop, they will be discarded
		 * because *cptr != TESTvalue.
		 */
		writeb(0x42, base);
		if (readb(base) != 0x42) {
			BUGMSG2(D_INIT_REASONS, "(read only)\n");
			BUGMSG2(D_INIT_REASONS, "S3: ");
			goto out2;
		}
		BUGMSG2(D_INIT_REASONS, "\n");
		BUGMSG2(D_INIT_REASONS, "S3: ");
		BUGLVL(D_INIT_REASONS) numprint = 0;
		iomem[index] = base;
		continue;
	out2:
		iounmap(base);
	out1:
		release_mem_region(*p, MIRROR_SIZE);
	out:
		*p-- = shmems[--numshmems];
		index--;
	}
	BUGMSG2(D_INIT, "\n");

	if (!numshmems) {
		BUGMSG2(D_NORMAL, "S3: No ARCnet cards found.\n");
		for (port = &ports[0]; port < ports + numports; port++)
			release_region(*port, ARCNET_TOTAL_SIZE);
		kfree(shmems);
		kfree(iomem);
		return;
	}
	/* Stage 4: something of a dummy, to report the shmems that are
	 * still possible after stage 3.
	 */
	numprint = -1;
	for (p = &shmems[0]; p < shmems + numshmems; p++) {
		numprint++;
		numprint %= 8;
		if (!numprint) {
			BUGMSG2(D_INIT, "\n");
			BUGMSG2(D_INIT, "S4: ");
		}
		BUGMSG2(D_INIT, "%lXh ", *p);
	}
	BUGMSG2(D_INIT, "\n");

	/* Stage 5: for any ports that have the correct status, can disable
	 * the RESET flag, and (if no irq is given) generate an autoirq,
	 * register an ARCnet device.
	 *
	 * Currently, we can only register one device per probe, so quit
	 * after the first one is found.
	 */
	numprint = -1;
	for (port = &ports[0]; port < ports + numports; port++) {
		int found = 0;
		numprint++;
		numprint %= 8;
		if (!numprint) {
			BUGMSG2(D_INIT, "\n");
			BUGMSG2(D_INIT, "S5: ");
		}
		BUGMSG2(D_INIT, "%Xh ", *port);

		ioaddr = *port;
		status = ASTATUS();

		if ((status & 0x9D)
		    != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
			BUGMSG2(D_INIT_REASONS, "(status=%Xh)\n", status);
			BUGMSG2(D_INIT_REASONS, "S5: ");
			BUGLVL(D_INIT_REASONS) numprint = 0;
			release_region(*port, ARCNET_TOTAL_SIZE);
			*port-- = ports[--numports];
			continue;
		}
		ACOMMAND(CFLAGScmd | RESETclear | CONFIGclear);
		status = ASTATUS();
		if (status & RESETflag) {
			BUGMSG2(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
				status);
			BUGMSG2(D_INIT_REASONS, "S5: ");
			BUGLVL(D_INIT_REASONS) numprint = 0;
			release_region(*port, ARCNET_TOTAL_SIZE);
			*port-- = ports[--numports];
			continue;
		}
		/* skip this completely if an IRQ was given, because maybe
		 * we're on a machine that locks during autoirq!
		 */
		if (!irq) {
			/* if we do this, we're sure to get an IRQ since the
			 * card has just reset and the NORXflag is on until
			 * we tell it to start receiving.
			 */
			airqmask = probe_irq_on();
			AINTMASK(NORXflag);
			udelay(1);
			AINTMASK(0);
			airq = probe_irq_off(airqmask);

			if (airq <= 0) {
				BUGMSG2(D_INIT_REASONS, "(airq=%d)\n", airq);
				BUGMSG2(D_INIT_REASONS, "S5: ");
				BUGLVL(D_INIT_REASONS) numprint = 0;
				release_region(*port, ARCNET_TOTAL_SIZE);
				*port-- = ports[--numports];
				continue;
			}
		} else {
			airq = irq;
		}

		BUGMSG2(D_INIT, "(%d,", airq);
		openparen = 1;

		/* Everything seems okay.  But which shmem, if any, puts
		 * back its signature byte when the card is reset?
		 *
		 * If there are multiple cards installed, there might be
		 * multiple shmems still in the list.
		 */
#ifdef FAST_PROBE
		if (numports > 1 || numshmems > 1) {
			inb(_RESET);
			mdelay(RESETtime);
		} else {
			/* just one shmem and port, assume they match */
			writeb(TESTvalue, iomem[0]);
		}
#else
		inb(_RESET);
		mdelay(RESETtime);
#endif

		for (index = 0; index < numshmems; index++) {
			u_long ptr = shmems[index];
			void __iomem *base = iomem[index];

			if (readb(base) == TESTvalue) {	/* found one */
				BUGMSG2(D_INIT, "%lXh)\n", *p);
				openparen = 0;

				/* register the card */
				if (com90xx_found(*port, airq, ptr, base) == 0)
					found = 1;
				numprint = -1;

				/* remove shmem from the list */
				shmems[index] = shmems[--numshmems];
				iomem[index] = iomem[numshmems];
				break;	/* go to the next I/O port */
			} else {
				BUGMSG2(D_INIT_REASONS, "%Xh-", readb(base));
			}
		}

		if (openparen) {
			BUGLVL(D_INIT) printk("no matching shmem)\n");
			BUGLVL(D_INIT_REASONS) printk("S5: ");
			BUGLVL(D_INIT_REASONS) numprint = 0;
		}
		if (!found)
			release_region(*port, ARCNET_TOTAL_SIZE);
		*port-- = ports[--numports];
	}

	BUGLVL(D_INIT_REASONS) printk("\n");

	/* Now put back TESTvalue on all leftover shmems. */
	for (index = 0; index < numshmems; index++) {
		writeb(TESTvalue, iomem[index]);
		iounmap(iomem[index]);
		release_mem_region(shmems[index], MIRROR_SIZE);
	}
	kfree(shmems);
	kfree(iomem);
}

static int check_mirror(unsigned long addr, size_t size)
{
	void __iomem *p;
	int res = -1;

	if (!request_mem_region(addr, size, "arcnet (90xx)"))
		return -1;

	p = ioremap(addr, size);
	if (p) {
		if (readb(p) == TESTvalue)
			res = 1;
		else
			res = 0;
		iounmap(p);
	}

	release_mem_region(addr, size);
	return res;
}

/* Set up the struct net_device associated with this card.  Called after
 * probing succeeds.
 */
static int __init com90xx_found(int ioaddr, int airq, u_long shmem, void __iomem *p)
{
	struct net_device *dev = NULL;
	struct arcnet_local *lp;
	u_long first_mirror, last_mirror;
	int mirror_size;

	/* allocate struct net_device */
	dev = alloc_arcdev(device);
	if (!dev) {
		BUGMSG2(D_NORMAL, "com90xx: Can't allocate device!\n");
		iounmap(p);
		release_mem_region(shmem, MIRROR_SIZE);
		return -ENOMEM;
	}
	lp = netdev_priv(dev);
	/* find the real shared memory start/end points, including mirrors */

	/* guess the actual size of one "memory mirror" - the number of
	 * bytes between copies of the shared memory.  On most cards, it's
	 * 2k (or there are no mirrors at all) but on some, it's 4k.
	 */
	mirror_size = MIRROR_SIZE;
	if (readb(p) == TESTvalue &&
	    check_mirror(shmem - MIRROR_SIZE, MIRROR_SIZE) == 0 &&
	    check_mirror(shmem - 2 * MIRROR_SIZE, MIRROR_SIZE) == 1)
		mirror_size = 2 * MIRROR_SIZE;

	first_mirror = shmem - mirror_size;
	while (check_mirror(first_mirror, mirror_size) == 1)
		first_mirror -= mirror_size;
	first_mirror += mirror_size;

	last_mirror = shmem + mirror_size;
	while (check_mirror(last_mirror, mirror_size) == 1)
		last_mirror += mirror_size;
	last_mirror -= mirror_size;

	dev->mem_start = first_mirror;
	dev->mem_end = last_mirror + MIRROR_SIZE - 1;

	iounmap(p);
	release_mem_region(shmem, MIRROR_SIZE);

	if (!request_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1, "arcnet (90xx)"))
		goto err_free_dev;

	/* reserve the irq */
	if (request_irq(airq, arcnet_interrupt, 0, "arcnet (90xx)", dev)) {
		BUGMSG(D_NORMAL, "Can't get IRQ %d!\n", airq);
		goto err_release_mem;
	}
	dev->irq = airq;

	/* Initialize the rest of the device structure. */
	lp->card_name = "COM90xx";
	lp->hw.command = com90xx_command;
	lp->hw.status = com90xx_status;
	lp->hw.intmask = com90xx_setmask;
	lp->hw.reset = com90xx_reset;
	lp->hw.owner = THIS_MODULE;
	lp->hw.copy_to_card = com90xx_copy_to_card;
	lp->hw.copy_from_card = com90xx_copy_from_card;
	lp->mem_start = ioremap(dev->mem_start, dev->mem_end - dev->mem_start + 1);
	if (!lp->mem_start) {
		BUGMSG(D_NORMAL, "Can't remap device memory!\n");
		goto err_free_irq;
	}

	/* get and check the station ID from offset 1 in shmem */
	dev->dev_addr[0] = readb(lp->mem_start + 1);

	dev->base_addr = ioaddr;

	BUGMSG(D_NORMAL, "COM90xx station %02Xh found at %03lXh, IRQ %d, "
	       "ShMem %lXh (%ld*%xh).\n",
	       dev->dev_addr[0],
	       dev->base_addr, dev->irq, dev->mem_start,
	 (dev->mem_end - dev->mem_start + 1) / mirror_size, mirror_size);

	if (register_netdev(dev))
		goto err_unmap;

	cards[numcards++] = dev;
	return 0;

err_unmap:
	iounmap(lp->mem_start);
err_free_irq:
	free_irq(dev->irq, dev);
err_release_mem:
	release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
err_free_dev:
	free_netdev(dev);
	return -EIO;
}


static void com90xx_command(struct net_device *dev, int cmd)
{
	short ioaddr = dev->base_addr;

	ACOMMAND(cmd);
}


static int com90xx_status(struct net_device *dev)
{
	short ioaddr = dev->base_addr;

	return ASTATUS();
}


static void com90xx_setmask(struct net_device *dev, int mask)
{
	short ioaddr = dev->base_addr;

	AINTMASK(mask);
}


/*
 * Do a hardware reset on the card, and set up necessary registers.
 * 
 * This should be called as little as possible, because it disrupts the
 * token on the network (causes a RECON) and requires a significant delay.
 *
 * However, it does make sure the card is in a defined state.
 */
static int com90xx_reset(struct net_device *dev, int really_reset)
{
	struct arcnet_local *lp = netdev_priv(dev);
	short ioaddr = dev->base_addr;

	BUGMSG(D_INIT, "Resetting (status=%02Xh)\n", ASTATUS());

	if (really_reset) {
		/* reset the card */
		inb(_RESET);
		mdelay(RESETtime);
	}
	ACOMMAND(CFLAGScmd | RESETclear);	/* clear flags & end reset */
	ACOMMAND(CFLAGScmd | CONFIGclear);

	/* don't do this until we verify that it doesn't hurt older cards! */
	/* outb(inb(_CONFIG) | ENABLE16flag, _CONFIG); */

	/* verify that the ARCnet signature byte is present */
	if (readb(lp->mem_start) != TESTvalue) {
		if (really_reset)
			BUGMSG(D_NORMAL, "reset failed: TESTvalue not present.\n");
		return 1;
	}
	/* enable extended (512-byte) packets */
	ACOMMAND(CONFIGcmd | EXTconf);

	/* clean out all the memory to make debugging make more sense :) */
	BUGLVL(D_DURING)
	    memset_io(lp->mem_start, 0x42, 2048);

	/* done!  return success. */
	return 0;
}

static void com90xx_copy_to_card(struct net_device *dev, int bufnum, int offset,
				 void *buf, int count)
{
	struct arcnet_local *lp = netdev_priv(dev);
	void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
	TIME("memcpy_toio", count, memcpy_toio(memaddr, buf, count));
}


static void com90xx_copy_from_card(struct net_device *dev, int bufnum, int offset,
				   void *buf, int count)
{
	struct arcnet_local *lp = netdev_priv(dev);
	void __iomem *memaddr = lp->mem_start + bufnum * 512 + offset;
	TIME("memcpy_fromio", count, memcpy_fromio(buf, memaddr, count));
}


MODULE_LICENSE("GPL");

static int __init com90xx_init(void)
{
	if (irq == 2)
		irq = 9;
	com90xx_probe();
	if (!numcards)
		return -EIO;
	return 0;
}

static void __exit com90xx_exit(void)
{
	struct net_device *dev;
	struct arcnet_local *lp;
	int count;

	for (count = 0; count < numcards; count++) {
		dev = cards[count];
		lp = netdev_priv(dev);

		unregister_netdev(dev);
		free_irq(dev->irq, dev);
		iounmap(lp->mem_start);
		release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
		release_mem_region(dev->mem_start, dev->mem_end - dev->mem_start + 1);
		free_netdev(dev);
	}
}

module_init(com90xx_init);
module_exit(com90xx_exit);

#ifndef MODULE
static int __init com90xx_setup(char *s)
{
	int ints[8];

	s = get_options(s, 8, ints);
	if (!ints[0] && !*s) {
		printk("com90xx: Disabled.\n");
		return 1;
	}

	switch (ints[0]) {
	default:		/* ERROR */
		printk("com90xx: Too many arguments.\n");
	case 3:		/* Mem address */
		shmem = ints[3];
	case 2:		/* IRQ */
		irq = ints[2];
	case 1:		/* IO address */
		io = ints[1];
	}

	if (*s)
		snprintf(device, sizeof(device), "%s", s);

	return 1;
}

__setup("com90xx=", com90xx_setup);
#endif
