/*
 * Linux ARCnet driver - COM90xx chipset (IO-mapped buffers)
 *
 * Written 1997 by David Woodhouse.
 * Written 1994-1999 by Avery Pennarun.
 * Written 1999-2000 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/kernel.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/bootmem.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>

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

/* Internal function declarations */

static int com90io_found(struct net_device *dev);
static void com90io_command(struct net_device *dev, int command);
static int com90io_status(struct net_device *dev);
static void com90io_setmask(struct net_device *dev, int mask);
static int com90io_reset(struct net_device *dev, int really_reset);
static void com90io_copy_to_card(struct net_device *dev, int bufnum, int offset,
				 void *buf, int count);
static void com90io_copy_from_card(struct net_device *dev, int bufnum,
				   int offset, void *buf, int count);

/* Handy defines for ARCnet specific stuff */

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

/****************************************************************************
 *                                                                          *
 * IO-mapped operation routines                                             *
 *                                                                          *
 ****************************************************************************/

#undef ONE_AT_A_TIME_TX
#undef ONE_AT_A_TIME_RX

static u_char get_buffer_byte(struct net_device *dev, unsigned offset)
{
	int ioaddr = dev->base_addr;

	arcnet_outb(offset >> 8, ioaddr, COM9026_REG_W_ADDR_HI);
	arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO);

	return arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA);
}

#ifdef ONE_AT_A_TIME_TX
static void put_buffer_byte(struct net_device *dev, unsigned offset,
			    u_char datum)
{
	int ioaddr = dev->base_addr;

	arcnet_outb(offset >> 8, ioaddr, COM9026_REG_W_ADDR_HI);
	arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO);

	arcnet_outb(datum, ioaddr, COM9026_REG_RW_MEMDATA);
}

#endif

static void get_whole_buffer(struct net_device *dev, unsigned offset,
			     unsigned length, char *dest)
{
	int ioaddr = dev->base_addr;

	arcnet_outb((offset >> 8) | AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI);
	arcnet_outb(offset & 0xff, ioaddr, COM9026_REG_W_ADDR_LO);

	while (length--)
#ifdef ONE_AT_A_TIME_RX
		*(dest++) = get_buffer_byte(dev, offset++);
#else
		*(dest++) = arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA);
#endif
}

static void put_whole_buffer(struct net_device *dev, unsigned offset,
			     unsigned length, char *dest)
{
	int ioaddr = dev->base_addr;

	arcnet_outb((offset >> 8) | AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI);
	arcnet_outb(offset & 0xff, ioaddr,COM9026_REG_W_ADDR_LO);

	while (length--)
#ifdef ONE_AT_A_TIME_TX
		put_buffer_byte(dev, offset++, *(dest++));
#else
		arcnet_outb(*(dest++), ioaddr, COM9026_REG_RW_MEMDATA);
#endif
}

/* We cannot probe for an IO mapped card either, although we can check that
 * it's where we were told it was, and even autoirq
 */
static int __init com90io_probe(struct net_device *dev)
{
	int ioaddr = dev->base_addr, status;
	unsigned long airqmask;

	if (BUGLVL(D_NORMAL)) {
		pr_info("%s\n", "COM90xx IO-mapped mode support (by David Woodhouse et el.)");
		pr_info("E-mail me if you actually test this driver, please!\n");
	}

	if (!ioaddr) {
		arc_printk(D_NORMAL, dev, "No autoprobe for IO mapped cards; you must specify the base address!\n");
		return -ENODEV;
	}
	if (!request_region(ioaddr, ARCNET_TOTAL_SIZE, "com90io probe")) {
		arc_printk(D_INIT_REASONS, dev, "IO request_region %x-%x failed\n",
			   ioaddr, ioaddr + ARCNET_TOTAL_SIZE - 1);
		return -ENXIO;
	}
	if (arcnet_inb(ioaddr, COM9026_REG_R_STATUS) == 0xFF) {
		arc_printk(D_INIT_REASONS, dev, "IO address %x empty\n",
			   ioaddr);
		goto err_out;
	}
	arcnet_inb(ioaddr, COM9026_REG_R_RESET);
	mdelay(RESETtime);

	status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);

	if ((status & 0x9D) != (NORXflag | RECONflag | TXFREEflag | RESETflag)) {
		arc_printk(D_INIT_REASONS, dev, "Status invalid (%Xh)\n",
			   status);
		goto err_out;
	}
	arc_printk(D_INIT_REASONS, dev, "Status after reset: %X\n", status);

	arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
		    ioaddr, COM9026_REG_W_COMMAND);

	arc_printk(D_INIT_REASONS, dev, "Status after reset acknowledged: %X\n",
		   status);

	status = arcnet_inb(ioaddr, COM9026_REG_R_STATUS);

	if (status & RESETflag) {
		arc_printk(D_INIT_REASONS, dev, "Eternal reset (status=%Xh)\n",
			   status);
		goto err_out;
	}
	arcnet_outb((0x16 | IOMAPflag) & ~ENABLE16flag,
		    ioaddr, COM9026_REG_RW_CONFIG);

	/* Read first loc'n of memory */

	arcnet_outb(AUTOINCflag, ioaddr, COM9026_REG_W_ADDR_HI);
	arcnet_outb(0, ioaddr,  COM9026_REG_W_ADDR_LO);

	status = arcnet_inb(ioaddr, COM9026_REG_RW_MEMDATA);
	if (status != 0xd1) {
		arc_printk(D_INIT_REASONS, dev, "Signature byte not found (%Xh instead).\n",
			   status);
		goto err_out;
	}
	if (!dev->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);
		dev->irq = probe_irq_off(airqmask);

		if ((int)dev->irq <= 0) {
			arc_printk(D_INIT_REASONS, dev, "Autoprobe IRQ failed\n");
			goto err_out;
		}
	}
	release_region(ioaddr, ARCNET_TOTAL_SIZE); /* end of probing */
	return com90io_found(dev);

err_out:
	release_region(ioaddr, ARCNET_TOTAL_SIZE);
	return -ENODEV;
}

/* Set up the struct net_device associated with this card.  Called after
 * probing succeeds.
 */
static int __init com90io_found(struct net_device *dev)
{
	struct arcnet_local *lp;
	int ioaddr = dev->base_addr;
	int err;

	/* Reserve the irq */
	if (request_irq(dev->irq, arcnet_interrupt, 0,
			"arcnet (COM90xx-IO)", dev)) {
		arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", dev->irq);
		return -ENODEV;
	}
	/* Reserve the I/O region */
	if (!request_region(dev->base_addr, ARCNET_TOTAL_SIZE,
			    "arcnet (COM90xx-IO)")) {
		free_irq(dev->irq, dev);
		return -EBUSY;
	}

	lp = netdev_priv(dev);
	lp->card_name = "COM90xx I/O";
	lp->hw.command = com90io_command;
	lp->hw.status = com90io_status;
	lp->hw.intmask = com90io_setmask;
	lp->hw.reset = com90io_reset;
	lp->hw.owner = THIS_MODULE;
	lp->hw.copy_to_card = com90io_copy_to_card;
	lp->hw.copy_from_card = com90io_copy_from_card;

	lp->config = (0x16 | IOMAPflag) & ~ENABLE16flag;
	arcnet_outb(lp->config, ioaddr, COM9026_REG_RW_CONFIG);

	/* get and check the station ID from offset 1 in shmem */

	dev->dev_addr[0] = get_buffer_byte(dev, 1);

	err = register_netdev(dev);
	if (err) {
		arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) & ~IOMAPflag,
			    ioaddr, COM9026_REG_RW_CONFIG);
		free_irq(dev->irq, dev);
		release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
		return err;
	}

	arc_printk(D_NORMAL, dev, "COM90IO: station %02Xh found at %03lXh, IRQ %d.\n",
		   dev->dev_addr[0], dev->base_addr, dev->irq);

	return 0;
}

/* 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 com90io_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 %s (status=%02Xh)\n",
		   dev->name, arcnet_inb(ioaddr, COM9026_REG_R_STATUS));

	if (really_reset) {
		/* reset the card */
		arcnet_inb(ioaddr, COM9026_REG_R_RESET);
		mdelay(RESETtime);
	}
	/* Set the thing to IO-mapped, 8-bit  mode */
	lp->config = (0x1C | IOMAPflag) & ~ENABLE16flag;
	arcnet_outb(lp->config, ioaddr, COM9026_REG_RW_CONFIG);

	arcnet_outb(CFLAGScmd | RESETclear, ioaddr, COM9026_REG_W_COMMAND);
					/* clear flags & end reset */
	arcnet_outb(CFLAGScmd | CONFIGclear, ioaddr, COM9026_REG_W_COMMAND);

	/* verify that the ARCnet signature byte is present */
	if (get_buffer_byte(dev, 0) != TESTvalue) {
		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);
	/* done!  return success. */
	return 0;
}

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

	arcnet_outb(cmd, ioaddr, COM9026_REG_W_COMMAND);
}

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

	return arcnet_inb(ioaddr, COM9026_REG_R_STATUS);
}

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

	arcnet_outb(mask, ioaddr, COM9026_REG_W_INTMASK);
}

static void com90io_copy_to_card(struct net_device *dev, int bufnum,
				 int offset, void *buf, int count)
{
	TIME(dev, "put_whole_buffer", count,
	     put_whole_buffer(dev, bufnum * 512 + offset, count, buf));
}

static void com90io_copy_from_card(struct net_device *dev, int bufnum,
				   int offset, void *buf, int count)
{
	TIME(dev, "get_whole_buffer", count,
	     get_whole_buffer(dev, bufnum * 512 + offset, count, buf));
}

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

module_param_hw(io, int, ioport, 0);
module_param_hw(irq, int, irq, 0);
module_param_string(device, device, sizeof(device), 0);
MODULE_LICENSE("GPL");

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

	s = get_options(s, 4, ints);
	if (!ints[0])
		return 0;
	switch (ints[0]) {
	default:		/* ERROR */
		pr_err("Too many arguments\n");
	case 2:		/* IRQ */
		irq = ints[2];
	case 1:		/* IO address */
		io = ints[1];
	}
	if (*s)
		snprintf(device, sizeof(device), "%s", s);
	return 1;
}
__setup("com90io=", com90io_setup);
#endif

static struct net_device *my_dev;

static int __init com90io_init(void)
{
	struct net_device *dev;
	int err;

	dev = alloc_arcdev(device);
	if (!dev)
		return -ENOMEM;

	dev->base_addr = io;
	dev->irq = irq;
	if (dev->irq == 2)
		dev->irq = 9;

	err = com90io_probe(dev);

	if (err) {
		free_netdev(dev);
		return err;
	}

	my_dev = dev;
	return 0;
}

static void __exit com90io_exit(void)
{
	struct net_device *dev = my_dev;
	int ioaddr = dev->base_addr;

	unregister_netdev(dev);

	/* In case the old driver is loaded later,
	 * set the thing back to MMAP mode
	 */
	arcnet_outb(arcnet_inb(ioaddr, COM9026_REG_RW_CONFIG) & ~IOMAPflag,
		    ioaddr, COM9026_REG_RW_CONFIG);

	free_irq(dev->irq, dev);
	release_region(dev->base_addr, ARCNET_TOTAL_SIZE);
	free_netdev(dev);
}

module_init(com90io_init)
module_exit(com90io_exit)
