/*
 * 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
 *
 * **********************
 */

#define pr_fmt(fmt) "arcnet:" KBUILD_MODNAME ": " fmt

#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 <linux/io.h>

#include "arcdevice.h"
#include "com9026.h"

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

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;
	}

	if (BUGLVL(D_NORMAL))
		pr_info("%s\n", "COM90xx chipset support");

	/* 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) {
			arc_cont(D_INIT, "\n");
			arc_cont(D_INIT, "S1: ");
		}
		arc_cont(D_INIT, "%Xh ", *port);

		ioaddr = *port;

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

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

	if (!numports) {
		arc_cont(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) {
			arc_cont(D_INIT, "\n");
			arc_cont(D_INIT, "S2: ");
		}
		arc_cont(D_INIT, "%Xh ", *port);
	}
	arc_cont(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) {
			arc_cont(D_INIT, "\n");
			arc_cont(D_INIT, "S3: ");
		}
		arc_cont(D_INIT, "%lXh ", *p);

		if (!request_mem_region(*p, MIRROR_SIZE, "arcnet (90xx)")) {
			arc_cont(D_INIT_REASONS, "(request_mem_region)\n");
			arc_cont(D_INIT_REASONS, "Stage 3: ");
			if (BUGLVL(D_INIT_REASONS))
				numprint = 0;
			goto out;
		}
		base = ioremap(*p, MIRROR_SIZE);
		if (!base) {
			arc_cont(D_INIT_REASONS, "(ioremap)\n");
			arc_cont(D_INIT_REASONS, "Stage 3: ");
			if (BUGLVL(D_INIT_REASONS))
				numprint = 0;
			goto out1;
		}
		if (arcnet_readb(base, COM9026_REG_R_STATUS) != TESTvalue) {
			arc_cont(D_INIT_REASONS, "(%02Xh != %02Xh)\n",
				 arcnet_readb(base, COM9026_REG_R_STATUS),
				 TESTvalue);
			arc_cont(D_INIT_REASONS, "S3: ");
			if (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.
		 */
		arcnet_writeb(0x42, base, COM9026_REG_W_INTMASK);
		if (arcnet_readb(base, COM9026_REG_R_STATUS) != 0x42) {
			arc_cont(D_INIT_REASONS, "(read only)\n");
			arc_cont(D_INIT_REASONS, "S3: ");
			goto out2;
		}
		arc_cont(D_INIT_REASONS, "\n");
		arc_cont(D_INIT_REASONS, "S3: ");
		if (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--;
	}
	arc_cont(D_INIT, "\n");

	if (!numshmems) {
		arc_cont(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) {
			arc_cont(D_INIT, "\n");
			arc_cont(D_INIT, "S4: ");
		}
		arc_cont(D_INIT, "%lXh ", *p);
	}
	arc_cont(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) {
			arc_cont(D_INIT, "\n");
			arc_cont(D_INIT, "S5: ");
		}
		arc_cont(D_INIT, "%Xh ", *port);

		ioaddr = *port;
		status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);

		if ((status & 0x9D)
		    != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
			arc_cont(D_INIT_REASONS, "(status=%Xh)\n", status);
			arc_cont(D_INIT_REASONS, "S5: ");
			if (BUGLVL(D_INIT_REASONS))
				numprint = 0;
			release_region(*port, ARCNET_TOTAL_SIZE);
			*port-- = ports[--numports];
			continue;
		}
		arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
			    ioaddr, COM9026_REG_W_COMMAND);
		status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
		if (status & RESETflag) {
			arc_cont(D_INIT_REASONS, " (eternal reset, status=%Xh)\n",
				 status);
			arc_cont(D_INIT_REASONS, "S5: ");
			if (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();
			arcnet_outb(NORXflag, ioaddr, COM9026_REG_W_INTMASK);
			udelay(1);
			arcnet_outb(0, ioaddr, COM9026_REG_W_INTMASK);
			airq = probe_irq_off(airqmask);

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

		arc_cont(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) {
			arcnet_inb(ioaddr, COM9026_REG_R_RESET);
			mdelay(RESETtime);
		} else {
			/* just one shmem and port, assume they match */
			arcnet_writeb(TESTvalue, iomem[0],
				      COM9026_REG_W_INTMASK);
		}
#else
		arcnet_inb(ioaddr, COM9026_REG_R_RESET);
		mdelay(RESETtime);
#endif

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

			if (arcnet_readb(base, COM9026_REG_R_STATUS) == TESTvalue) {	/* found one */
				arc_cont(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 {
				arc_cont(D_INIT_REASONS, "%Xh-",
					 arcnet_readb(base, COM9026_REG_R_STATUS));
			}
		}

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

	if (BUGLVL(D_INIT_REASONS))
		pr_cont("\n");

	/* Now put back TESTvalue on all leftover shmems. */
	for (index = 0; index < numshmems; index++) {
		arcnet_writeb(TESTvalue, iomem[index], COM9026_REG_W_INTMASK);
		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 (arcnet_readb(p, COM9026_REG_R_STATUS) == 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) {
		arc_cont(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 (arcnet_readb(p, COM9026_REG_R_STATUS) == 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)) {
		arc_printk(D_NORMAL, dev, "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) {
		arc_printk(D_NORMAL, dev, "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] = arcnet_readb(lp->mem_start, COM9026_REG_R_STATION);

	dev->base_addr = ioaddr;

	arc_printk(D_NORMAL, dev, "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;

	arcnet_outb(cmd, ioaddr, COM9026_REG_W_COMMAND);
}

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

	return arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
}

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

	arcnet_outb(mask, ioaddr, COM9026_REG_W_INTMASK);
}

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

	arc_printk(D_INIT, dev, "Resetting (status=%02Xh)\n",
		   arcnet_inb(ioaddr, COM9026_REG_R_STATUS));

	if (really_reset) {
		/* reset the card */
		arcnet_inb(ioaddr, COM9026_REG_R_RESET);
		mdelay(RESETtime);
	}
	/* clear flags & end reset */
	arcnet_outb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND);
	arcnet_outb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND);

#if 0
	/* don't do this until we verify that it doesn't hurt older cards! */
	arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) | ENABLE16flag,
		    ioaddr, COM9026_REG_RW_CONFIG);
#endif

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

	/* clean out all the memory to make debugging make more sense :) */
	if (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(dev, "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(dev, "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) {
		pr_notice("Disabled\n");
		return 1;
	}

	switch (ints[0]) {
	default:		/* ERROR */
		pr_err("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
