/*
 * Linux ARCnet driver - COM20020 chipset support
 *
 * Written 1997 by David Woodhouse.
 * 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/kernel.h>
#include <linux/types.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/io.h>

#include "arcdevice.h"
#include "com20020.h"

static const char * const clockrates[] = {
	"XXXXXXX", "XXXXXXXX", "XXXXXX", "2.5 Mb/s",
	"1.25Mb/s", "625 Kb/s", "312.5 Kb/s", "156.25 Kb/s",
	"Reserved", "Reserved", "Reserved"
};

static void com20020_command(struct net_device *dev, int command);
static int com20020_status(struct net_device *dev);
static void com20020_setmask(struct net_device *dev, int mask);
static int com20020_reset(struct net_device *dev, int really_reset);
static void com20020_copy_to_card(struct net_device *dev, int bufnum,
				  int offset, void *buf, int count);
static void com20020_copy_from_card(struct net_device *dev, int bufnum,
				    int offset, void *buf, int count);
static void com20020_set_mc_list(struct net_device *dev);
static void com20020_close(struct net_device *);

static void com20020_copy_from_card(struct net_device *dev, int bufnum,
				    int offset, void *buf, int count)
{
	int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;

	/* set up the address register */
	arcnet_outb((ofs >> 8) | RDDATAflag | AUTOINCflag,
		    ioaddr, COM20020_REG_W_ADDR_HI);
	arcnet_outb(ofs & 0xff, ioaddr, COM20020_REG_W_ADDR_LO);

	/* copy the data */
	TIME(dev, "insb", count,
	     arcnet_insb(ioaddr, COM20020_REG_RW_MEMDATA, buf, count));
}

static void com20020_copy_to_card(struct net_device *dev, int bufnum,
				  int offset, void *buf, int count)
{
	int ioaddr = dev->base_addr, ofs = 512 * bufnum + offset;

	/* set up the address register */
	arcnet_outb((ofs >> 8) | AUTOINCflag, ioaddr, COM20020_REG_W_ADDR_HI);
	arcnet_outb(ofs & 0xff, ioaddr, COM20020_REG_W_ADDR_LO);

	/* copy the data */
	TIME(dev, "outsb", count,
	     arcnet_outsb(ioaddr, COM20020_REG_RW_MEMDATA, buf, count));
}

/* Reset the card and check some basic stuff during the detection stage. */
int com20020_check(struct net_device *dev)
{
	int ioaddr = dev->base_addr, status;
	struct arcnet_local *lp = netdev_priv(dev);

	arcnet_outb(XTOcfg(3) | RESETcfg, ioaddr, COM20020_REG_W_CONFIG);
	udelay(5);
	arcnet_outb(XTOcfg(3), ioaddr, COM20020_REG_W_CONFIG);
	mdelay(RESETtime);

	lp->setup = lp->clockm ? 0 : (lp->clockp << 1);
	lp->setup2 = (lp->clockm << 4) | 8;

	/* CHECK: should we do this for SOHARD cards ? */
	/* Enable P1Mode for backplane mode */
	lp->setup = lp->setup | P1MODE;

	com20020_set_subaddress(lp, ioaddr, SUB_SETUP1);
	arcnet_outb(lp->setup, ioaddr, COM20020_REG_W_XREG);

	if (lp->clockm != 0) {
		com20020_set_subaddress(lp, ioaddr, SUB_SETUP2);
		arcnet_outb(lp->setup2, ioaddr, COM20020_REG_W_XREG);

		/* must now write the magic "restart operation" command */
		mdelay(1);
		arcnet_outb(STARTIOcmd, ioaddr, COM20020_REG_W_COMMAND);
	}

	lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE;
	/* set node ID to 0x42 (but transmitter is disabled, so it's okay) */
	arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
	arcnet_outb(0x42, ioaddr, COM20020_REG_W_XREG);

	status = arcnet_inb(ioaddr, COM20020_REG_R_STATUS);

	if ((status & 0x99) != (NORXflag | TXFREEflag | RESETflag)) {
		arc_printk(D_NORMAL, dev, "status invalid (%Xh).\n", status);
		return -ENODEV;
	}
	arc_printk(D_INIT_REASONS, dev, "status after reset: %X\n", status);

	/* Enable TX */
	lp->config |= TXENcfg;
	arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
	arcnet_outb(arcnet_inb(ioaddr, 8), ioaddr, COM20020_REG_W_XREG);

	arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
		    ioaddr, COM20020_REG_W_COMMAND);
	status = arcnet_inb(ioaddr, COM20020_REG_R_STATUS);
	arc_printk(D_INIT_REASONS, dev, "status after reset acknowledged: %X\n",
		   status);

	/* Read first location of memory */
	arcnet_outb(0 | RDDATAflag | AUTOINCflag,
		    ioaddr, COM20020_REG_W_ADDR_HI);
	arcnet_outb(0, ioaddr, COM20020_REG_W_ADDR_LO);

	status = arcnet_inb(ioaddr, COM20020_REG_RW_MEMDATA);
	if (status != TESTvalue) {
		arc_printk(D_NORMAL, dev, "Signature byte not found (%02Xh != D1h).\n",
			   status);
		return -ENODEV;
	}
	return 0;
}

static int com20020_set_hwaddr(struct net_device *dev, void *addr)
{
	int ioaddr = dev->base_addr;
	struct arcnet_local *lp = netdev_priv(dev);
	struct sockaddr *hwaddr = addr;

	memcpy(dev->dev_addr, hwaddr->sa_data, 1);
	com20020_set_subaddress(lp, ioaddr, SUB_NODE);
	arcnet_outb(dev->dev_addr[0], ioaddr, COM20020_REG_W_XREG);

	return 0;
}

const struct net_device_ops com20020_netdev_ops = {
	.ndo_open	= arcnet_open,
	.ndo_stop	= arcnet_close,
	.ndo_start_xmit = arcnet_send_packet,
	.ndo_tx_timeout = arcnet_timeout,
	.ndo_set_mac_address = com20020_set_hwaddr,
	.ndo_set_rx_mode = com20020_set_mc_list,
};

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

	/* Initialize the rest of the device structure. */

	lp = netdev_priv(dev);

	lp->hw.owner = THIS_MODULE;
	lp->hw.command = com20020_command;
	lp->hw.status = com20020_status;
	lp->hw.intmask = com20020_setmask;
	lp->hw.reset = com20020_reset;
	lp->hw.copy_to_card = com20020_copy_to_card;
	lp->hw.copy_from_card = com20020_copy_from_card;
	lp->hw.close = com20020_close;

	/* FIXME: do this some other way! */
	if (!dev->dev_addr[0])
		dev->dev_addr[0] = arcnet_inb(ioaddr, 8);

	com20020_set_subaddress(lp, ioaddr, SUB_SETUP1);
	arcnet_outb(lp->setup, ioaddr, COM20020_REG_W_XREG);

	if (lp->card_flags & ARC_CAN_10MBIT) {
		com20020_set_subaddress(lp, ioaddr, SUB_SETUP2);
		arcnet_outb(lp->setup2, ioaddr, COM20020_REG_W_XREG);

		/* must now write the magic "restart operation" command */
		mdelay(1);
		arcnet_outb(STARTIOcmd, ioaddr, COM20020_REG_W_COMMAND);
	}

	lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2) | SUB_NODE;
	/* Default 0x38 + register: Node ID */
	arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
	arcnet_outb(dev->dev_addr[0], ioaddr, COM20020_REG_W_XREG);

	/* reserve the irq */
	if (request_irq(dev->irq, arcnet_interrupt, shared,
			"arcnet (COM20020)", dev)) {
		arc_printk(D_NORMAL, dev, "Can't get IRQ %d!\n", dev->irq);
		return -ENODEV;
	}

	dev->base_addr = ioaddr;

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

	if (lp->backplane)
		arc_printk(D_NORMAL, dev, "Using backplane mode.\n");

	if (lp->timeout != 3)
		arc_printk(D_NORMAL, dev, "Using extended timeout value of %d\n",
			   lp->timeout);

	arc_printk(D_NORMAL, dev, "Using CKP %d - data rate %s\n",
		   lp->setup >> 1,
		   clockrates[3 -
			      ((lp->setup2 & 0xF0) >> 4) +
			      ((lp->setup & 0x0F) >> 1)]);
			/* The clockrates array index looks very fragile.
			 * It seems like it could have negative indexing.
			 */

	if (register_netdev(dev)) {
		free_irq(dev->irq, dev);
		return -EIO;
	}
	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 com20020_reset(struct net_device *dev, int really_reset)
{
	struct arcnet_local *lp = netdev_priv(dev);
	u_int ioaddr = dev->base_addr;
	u_char inbyte;

	arc_printk(D_DEBUG, dev, "%s: %d: %s: dev: %p, lp: %p, dev->name: %s\n",
		   __FILE__, __LINE__, __func__, dev, lp, dev->name);
	arc_printk(D_INIT, dev, "Resetting %s (status=%02Xh)\n",
		   dev->name, arcnet_inb(ioaddr, COM20020_REG_R_STATUS));

	arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
	lp->config = TXENcfg | (lp->timeout << 3) | (lp->backplane << 2);
	/* power-up defaults */
	arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
	arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);

	if (really_reset) {
		/* reset the card */
		arcnet_outb(lp->config | RESETcfg, ioaddr, COM20020_REG_W_CONFIG);
		udelay(5);
		arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
		mdelay(RESETtime * 2);
				/* COM20020 seems to be slower sometimes */
	}
	/* clear flags & end reset */
	arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
	arcnet_outb(CFLAGScmd | RESETclear | CONFIGclear,
		    ioaddr, COM20020_REG_W_COMMAND);

	/* verify that the ARCnet signature byte is present */
	arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);

	com20020_copy_from_card(dev, 0, 0, &inbyte, 1);
	arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);
	if (inbyte != TESTvalue) {
		arc_printk(D_DEBUG, dev, "%s: %d: %s\n",
			   __FILE__, __LINE__, __func__);
		arc_printk(D_NORMAL, dev, "reset failed: TESTvalue not present.\n");
		return 1;
	}
	/* enable extended (512-byte) packets */
	arcnet_outb(CONFIGcmd | EXTconf, ioaddr, COM20020_REG_W_COMMAND);

	arc_printk(D_DEBUG, dev, "%s: %d: %s\n", __FILE__, __LINE__, __func__);

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

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

	arc_printk(D_DURING, dev, "Setting mask to %x at %x\n", mask, ioaddr);
	arcnet_outb(mask, ioaddr, COM20020_REG_W_INTMASK);
}

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

	arcnet_outb(cmd, ioaddr, COM20020_REG_W_COMMAND);
}

static int com20020_status(struct net_device *dev)
{
	u_int ioaddr = dev->base_addr;

	return arcnet_inb(ioaddr, COM20020_REG_R_STATUS) +
		(arcnet_inb(ioaddr, COM20020_REG_R_DIAGSTAT) << 8);
}

static void com20020_close(struct net_device *dev)
{
	struct arcnet_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;

	/* disable transmitter */
	lp->config &= ~TXENcfg;
	arcnet_outb(lp->config, ioaddr, COM20020_REG_W_CONFIG);
}

/* Set or clear the multicast filter for this adaptor.
 * num_addrs == -1    Promiscuous mode, receive all packets
 * num_addrs == 0       Normal mode, clear multicast list
 * num_addrs > 0        Multicast mode, receive normal and MC packets, and do
 *                      best-effort filtering.
 *      FIXME - do multicast stuff, not just promiscuous.
 */
static void com20020_set_mc_list(struct net_device *dev)
{
	struct arcnet_local *lp = netdev_priv(dev);
	int ioaddr = dev->base_addr;

	if ((dev->flags & IFF_PROMISC) && (dev->flags & IFF_UP)) {
		/* Enable promiscuous mode */
		if (!(lp->setup & PROMISCset))
			arc_printk(D_NORMAL, dev, "Setting promiscuous flag...\n");
		com20020_set_subaddress(lp, ioaddr, SUB_SETUP1);
		lp->setup |= PROMISCset;
		arcnet_outb(lp->setup, ioaddr, COM20020_REG_W_XREG);
	} else {
		/* Disable promiscuous mode, use normal mode */
		if ((lp->setup & PROMISCset))
			arc_printk(D_NORMAL, dev, "Resetting promiscuous flag...\n");
		com20020_set_subaddress(lp, ioaddr, SUB_SETUP1);
		lp->setup &= ~PROMISCset;
		arcnet_outb(lp->setup, ioaddr, COM20020_REG_W_XREG);
	}
}

#if defined(CONFIG_ARCNET_COM20020_PCI_MODULE) || \
    defined(CONFIG_ARCNET_COM20020_ISA_MODULE) || \
    defined(CONFIG_ARCNET_COM20020_CS_MODULE)
EXPORT_SYMBOL(com20020_check);
EXPORT_SYMBOL(com20020_found);
EXPORT_SYMBOL(com20020_netdev_ops);
#endif

MODULE_LICENSE("GPL");

#ifdef MODULE

static int __init com20020_module_init(void)
{
	if (BUGLVL(D_NORMAL))
		pr_info("%s\n", "COM20020 chipset support (by David Woodhouse et al.)");
	return 0;
}

static void __exit com20020_module_exit(void)
{
}
module_init(com20020_module_init);
module_exit(com20020_module_exit);
#endif				/* MODULE */
