/*
 *  Amiga Linux/m68k and Linux/PPC Zorro NS8390 Ethernet Driver
 *
 *  (C) Copyright 1998-2000 by some Elitist 680x0 Users(TM)
 *
 *  ---------------------------------------------------------------------------
 *
 *  This program is based on all the other NE2000 drivers for Linux
 *
 *  ---------------------------------------------------------------------------
 *
 *  This file is subject to the terms and conditions of the GNU General Public
 *  License.  See the file COPYING in the main directory of the Linux
 *  distribution for more details.
 *
 *  ---------------------------------------------------------------------------
 *
 *  The Ariadne II and X-Surf are Zorro-II boards containing Realtek RTL8019AS
 *  Ethernet Controllers.
 */

#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/zorro.h>
#include <linux/jiffies.h>

#include <asm/irq.h>
#include <asm/amigaints.h>
#include <asm/amigahw.h>

#define EI_SHIFT(x)		(ei_local->reg_offset[x])
#define ei_inb(port)		in_8(port)
#define ei_outb(val, port)	out_8(port, val)
#define ei_inb_p(port)		in_8(port)
#define ei_outb_p(val, port)	out_8(port, val)

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

#include "lib8390.c"

#define DRV_NAME	"zorro8390"

#define NE_BASE		(dev->base_addr)
#define NE_CMD		(0x00 * 2)
#define NE_DATAPORT	(0x10 * 2)	/* NatSemi-defined port window offset */
#define NE_RESET	(0x1f * 2)	/* Issue a read to reset,
					 * a write to clear. */
#define NE_IO_EXTENT	(0x20 * 2)

#define NE_EN0_ISR	(0x07 * 2)
#define NE_EN0_DCFG	(0x0e * 2)

#define NE_EN0_RSARLO	(0x08 * 2)
#define NE_EN0_RSARHI	(0x09 * 2)
#define NE_EN0_RCNTLO	(0x0a * 2)
#define NE_EN0_RXCR	(0x0c * 2)
#define NE_EN0_TXCR	(0x0d * 2)
#define NE_EN0_RCNTHI	(0x0b * 2)
#define NE_EN0_IMR	(0x0f * 2)

#define NESM_START_PG	0x40	/* First page of TX buffer */
#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */

#define WORDSWAP(a)	((((a) >> 8) & 0xff) | ((a) << 8))

static struct card_info {
	zorro_id id;
	const char *name;
	unsigned int offset;
} cards[] = {
	{ ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, "Ariadne II", 0x0600 },
	{ ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, "X-Surf", 0x8600 },
};

/* Hard reset the card.  This used to pause for the same period that a
 * 8390 reset command required, but that shouldn't be necessary.
 */
static void zorro8390_reset_8390(struct net_device *dev)
{
	unsigned long reset_start_time = jiffies;

	if (ei_debug > 1)
		netdev_dbg(dev, "resetting - t=%ld...\n", jiffies);

	z_writeb(z_readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);

	ei_status.txing = 0;
	ei_status.dmaing = 0;

	/* This check _should_not_ be necessary, omit eventually. */
	while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RESET) == 0)
		if (time_after(jiffies, reset_start_time + 2 * HZ / 100)) {
			netdev_warn(dev, "%s: did not complete\n", __func__);
			break;
		}
	z_writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR);	/* Ack intr */
}

/* 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 zorro8390_get_8390_hdr(struct net_device *dev,
				   struct e8390_pkt_hdr *hdr, int ring_page)
{
	int nic_base = dev->base_addr;
	int cnt;
	short *ptrs;

	/* This *shouldn't* happen.
	 * If it does, it's the last thing you'll see
	 */
	if (ei_status.dmaing) {
		netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
			   __func__, ei_status.dmaing, ei_status.irqlock);
		return;
	}

	ei_status.dmaing |= 0x01;
	z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD);
	z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
	z_writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
	z_writeb(0, nic_base + NE_EN0_RCNTHI);
	z_writeb(0, nic_base + NE_EN0_RSARLO);		/* On page boundary */
	z_writeb(ring_page, nic_base + NE_EN0_RSARHI);
	z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);

	ptrs = (short *)hdr;
	for (cnt = 0; cnt < sizeof(struct e8390_pkt_hdr) >> 1; cnt++)
		*ptrs++ = z_readw(NE_BASE + NE_DATAPORT);

	z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr */

	hdr->count = WORDSWAP(hdr->count);

	ei_status.dmaing &= ~0x01;
}

/* Block input and output, similar to the Crynwr packet driver.
 * If you are porting to a new ethercard, look at the packet driver source
 * for hints. The NEx000 doesn't share the on-board packet memory --
 * you have to put the packet out through the "remote DMA" dataport
 * using z_writeb.
 */
static void zorro8390_block_input(struct net_device *dev, int count,
				  struct sk_buff *skb, int ring_offset)
{
	int nic_base = dev->base_addr;
	char *buf = skb->data;
	short *ptrs;
	int cnt;

	/* This *shouldn't* happen.
	 * If it does, it's the last thing you'll see
	 */
	if (ei_status.dmaing) {
		netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
			   __func__, ei_status.dmaing, ei_status.irqlock);
		return;
	}
	ei_status.dmaing |= 0x01;
	z_writeb(E8390_NODMA + E8390_PAGE0 + E8390_START, nic_base + NE_CMD);
	z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
	z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
	z_writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
	z_writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
	z_writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
	z_writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
	ptrs = (short *)buf;
	for (cnt = 0; cnt < count >> 1; cnt++)
		*ptrs++ = z_readw(NE_BASE + NE_DATAPORT);
	if (count & 0x01)
		buf[count - 1] = z_readb(NE_BASE + NE_DATAPORT);

	z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr */
	ei_status.dmaing &= ~0x01;
}

static void zorro8390_block_output(struct net_device *dev, int count,
				   const unsigned char *buf,
				   const int start_page)
{
	int nic_base = NE_BASE;
	unsigned long dma_start;
	short *ptrs;
	int cnt;

	/* Round the count up for word writes.  Do we need to do this?
	 * What effect will an odd byte count have on the 8390?
	 * I should check someday.
	 */
	if (count & 0x01)
		count++;

	/* This *shouldn't* happen.
	 * If it does, it's the last thing you'll see
	 */
	if (ei_status.dmaing) {
		netdev_err(dev, "%s: DMAing conflict [DMAstat:%d][irqlock:%d]\n",
			   __func__, ei_status.dmaing, ei_status.irqlock);
		return;
	}
	ei_status.dmaing |= 0x01;
	/* We should already be in page 0, but to be safe... */
	z_writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);

	z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);

	/* Now the normal output. */
	z_writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
	z_writeb(count >> 8,   nic_base + NE_EN0_RCNTHI);
	z_writeb(0x00, nic_base + NE_EN0_RSARLO);
	z_writeb(start_page, nic_base + NE_EN0_RSARHI);

	z_writeb(E8390_RWRITE + E8390_START, nic_base + NE_CMD);
	ptrs = (short *)buf;
	for (cnt = 0; cnt < count >> 1; cnt++)
		z_writew(*ptrs++, NE_BASE + NE_DATAPORT);

	dma_start = jiffies;

	while ((z_readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
		if (time_after(jiffies, dma_start + 2 * HZ / 100)) {
					/* 20ms */
			netdev_err(dev, "timeout waiting for Tx RDC\n");
			zorro8390_reset_8390(dev);
			__NS8390_init(dev, 1);
			break;
		}

	z_writeb(ENISR_RDC, nic_base + NE_EN0_ISR);	/* Ack intr */
	ei_status.dmaing &= ~0x01;
}

static int zorro8390_open(struct net_device *dev)
{
	__ei_open(dev);
	return 0;
}

static int zorro8390_close(struct net_device *dev)
{
	if (ei_debug > 1)
		netdev_dbg(dev, "Shutting down ethercard\n");
	__ei_close(dev);
	return 0;
}

static void zorro8390_remove_one(struct zorro_dev *z)
{
	struct net_device *dev = zorro_get_drvdata(z);

	unregister_netdev(dev);
	free_irq(IRQ_AMIGA_PORTS, dev);
	release_mem_region(ZTWO_PADDR(dev->base_addr), NE_IO_EXTENT * 2);
	free_netdev(dev);
}

static struct zorro_device_id zorro8390_zorro_tbl[] = {
	{ ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, },
	{ ZORRO_PROD_INDIVIDUAL_COMPUTERS_X_SURF, },
	{ 0 }
};
MODULE_DEVICE_TABLE(zorro, zorro8390_zorro_tbl);

static const struct net_device_ops zorro8390_netdev_ops = {
	.ndo_open		= zorro8390_open,
	.ndo_stop		= zorro8390_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 zorro8390_init(struct net_device *dev, unsigned long board,
			  const char *name, unsigned long ioaddr)
{
	int i;
	int err;
	unsigned char SA_prom[32];
	int start_page, stop_page;
	static u32 zorro8390_offsets[16] = {
		0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
		0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
	};

	/* Reset card. Who knows what dain-bramaged state it was left in. */
	{
		unsigned long reset_start_time = jiffies;

		z_writeb(z_readb(ioaddr + NE_RESET), ioaddr + NE_RESET);

		while ((z_readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
			if (time_after(jiffies,
				       reset_start_time + 2 * HZ / 100)) {
				netdev_warn(dev, "not found (no reset ack)\n");
				return -ENODEV;
			}

		z_writeb(0xff, ioaddr + NE_EN0_ISR);	/* Ack all intr. */
	}

	/* Read the 16 bytes of station address PROM.
	 * We must first initialize registers,
	 * similar to NS8390_init(eifdev, 0).
	 * We can't reliably read the SAPROM address without this.
	 * (I learned the hard way!).
	 */
	{
		static const struct {
			u32 value;
			u32 offset;
		} program_seq[] = {
			{E8390_NODMA + E8390_PAGE0 + E8390_STOP, NE_CMD},
						/* Select page 0 */
			{0x48,	NE_EN0_DCFG},	/* 0x48: Set byte-wide access */
			{0x00,	NE_EN0_RCNTLO},	/* Clear the count regs */
			{0x00,	NE_EN0_RCNTHI},
			{0x00,	NE_EN0_IMR},	/* Mask completion irq */
			{0xFF,	NE_EN0_ISR},
			{E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */
			{E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode */
			{32,	NE_EN0_RCNTLO},
			{0x00,	NE_EN0_RCNTHI},
			{0x00,	NE_EN0_RSARLO},	/* DMA starting at 0x0000 */
			{0x00,	NE_EN0_RSARHI},
			{E8390_RREAD + E8390_START, NE_CMD},
		};
		for (i = 0; i < ARRAY_SIZE(program_seq); i++)
			z_writeb(program_seq[i].value,
				 ioaddr + program_seq[i].offset);
	}
	for (i = 0; i < 16; i++) {
		SA_prom[i] = z_readb(ioaddr + NE_DATAPORT);
		(void)z_readb(ioaddr + NE_DATAPORT);
	}

	/* We must set the 8390 for word mode. */
	z_writeb(0x49, ioaddr + NE_EN0_DCFG);
	start_page = NESM_START_PG;
	stop_page = NESM_STOP_PG;

	dev->base_addr = ioaddr;
	dev->irq = IRQ_AMIGA_PORTS;

	/* Install the Interrupt handler */
	i = request_irq(IRQ_AMIGA_PORTS, __ei_interrupt,
			IRQF_SHARED, DRV_NAME, dev);
	if (i)
		return i;

	for (i = 0; i < ETH_ALEN; i++)
		dev->dev_addr[i] = SA_prom[i];

	pr_debug("Found ethernet address: %pM\n", dev->dev_addr);

	ei_status.name = name;
	ei_status.tx_start_page = start_page;
	ei_status.stop_page = stop_page;
	ei_status.word16 = 1;

	ei_status.rx_start_page = start_page + TX_PAGES;

	ei_status.reset_8390 = zorro8390_reset_8390;
	ei_status.block_input = zorro8390_block_input;
	ei_status.block_output = zorro8390_block_output;
	ei_status.get_8390_hdr = zorro8390_get_8390_hdr;
	ei_status.reg_offset = zorro8390_offsets;

	dev->netdev_ops = &zorro8390_netdev_ops;
	__NS8390_init(dev, 0);
	err = register_netdev(dev);
	if (err) {
		free_irq(IRQ_AMIGA_PORTS, dev);
		return err;
	}

	netdev_info(dev, "%s at 0x%08lx, Ethernet Address %pM\n",
		    name, board, dev->dev_addr);

	return 0;
}

static int zorro8390_init_one(struct zorro_dev *z,
			      const struct zorro_device_id *ent)
{
	struct net_device *dev;
	unsigned long board, ioaddr;
	int err, i;

	for (i = ARRAY_SIZE(cards) - 1; i >= 0; i--)
		if (z->id == cards[i].id)
			break;
	if (i < 0)
		return -ENODEV;

	board = z->resource.start;
	ioaddr = board + cards[i].offset;
	dev = ____alloc_ei_netdev(0);
	if (!dev)
		return -ENOMEM;
	if (!request_mem_region(ioaddr, NE_IO_EXTENT * 2, DRV_NAME)) {
		free_netdev(dev);
		return -EBUSY;
	}
	err = zorro8390_init(dev, board, cards[i].name, ZTWO_VADDR(ioaddr));
	if (err) {
		release_mem_region(ioaddr, NE_IO_EXTENT * 2);
		free_netdev(dev);
		return err;
	}
	zorro_set_drvdata(z, dev);
	return 0;
}

static struct zorro_driver zorro8390_driver = {
	.name		= "zorro8390",
	.id_table	= zorro8390_zorro_tbl,
	.probe		= zorro8390_init_one,
	.remove		= zorro8390_remove_one,
};

static int __init zorro8390_init_module(void)
{
	return zorro_register_driver(&zorro8390_driver);
}

static void __exit zorro8390_cleanup_module(void)
{
	zorro_unregister_driver(&zorro8390_driver);
}

module_init(zorro8390_init_module);
module_exit(zorro8390_cleanup_module);

MODULE_LICENSE("GPL");
