/*
 *  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;
	struct ei_device *ei_local = netdev_priv(dev);

	netif_dbg(ei_local, hw, 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_warn(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_warn(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)
{
	struct ei_device *ei_local = netdev_priv(dev);

	netif_dbg(ei_local, ifdown, 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,
#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, void __iomem *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 = (unsigned long)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");
