/*
 *  linux/drivers/acorn/net/etherh.c
 *
 *  Copyright (C) 2000-2002 Russell King
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 *
 * NS8390 I-cubed EtherH and ANT EtherM specific driver
 * Thanks to I-Cubed for information on their cards.
 * EtherM conversion (C) 1999 Chris Kemp and Tim Watterton
 * EtherM integration (C) 2000 Aleph One Ltd (Tak-Shing Chan)
 * EtherM integration re-engineered by Russell King.
 *
 * Changelog:
 *  08-12-1996	RMK	1.00	Created
 *		RMK	1.03	Added support for EtherLan500 cards
 *  23-11-1997	RMK	1.04	Added media autodetection
 *  16-04-1998	RMK	1.05	Improved media autodetection
 *  10-02-2000	RMK	1.06	Updated for 2.3.43
 *  13-05-2000	RMK	1.07	Updated for 2.3.99-pre8
 *  12-10-1999  CK/TEW		EtherM driver first release
 *  21-12-2000	TTC		EtherH/EtherM integration
 *  25-12-2000	RMK	1.08	Clean integration of EtherM into this driver.
 *  03-01-2002	RMK	1.09	Always enable IRQs if we're in the nic slot.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/ethtool.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <linux/jiffies.h>

#include <asm/system.h>
#include <asm/ecard.h>
#include <asm/io.h>

#include "../8390.h"

#define NET_DEBUG  0
#define DEBUG_INIT 2

#define DRV_NAME	"etherh"
#define DRV_VERSION	"1.11"

static unsigned int net_debug = NET_DEBUG;

struct etherh_priv {
	void __iomem	*ioc_fast;
	void __iomem	*memc;
	void __iomem	*dma_base;
	unsigned int	id;
	void __iomem	*ctrl_port;
	unsigned char	ctrl;
	u32		supported;
};

struct etherh_data {
	unsigned long	ns8390_offset;
	unsigned long	dataport_offset;
	unsigned long	ctrlport_offset;
	int		ctrl_ioc;
	const char	name[16];
	u32		supported;
	unsigned char	tx_start_page;
	unsigned char	stop_page;
};

MODULE_AUTHOR("Russell King");
MODULE_DESCRIPTION("EtherH/EtherM driver");
MODULE_LICENSE("GPL");

static char version[] __initdata =
	"EtherH/EtherM Driver (c) 2002-2004 Russell King " DRV_VERSION "\n";

#define ETHERH500_DATAPORT	0x800	/* MEMC */
#define ETHERH500_NS8390	0x000	/* MEMC */
#define ETHERH500_CTRLPORT	0x800	/* IOC  */

#define ETHERH600_DATAPORT	0x040	/* MEMC */
#define ETHERH600_NS8390	0x800	/* MEMC */
#define ETHERH600_CTRLPORT	0x200	/* MEMC */

#define ETHERH_CP_IE		1
#define ETHERH_CP_IF		2
#define ETHERH_CP_HEARTBEAT	2

#define ETHERH_TX_START_PAGE	1
#define ETHERH_STOP_PAGE	127

/*
 * These came from CK/TEW
 */
#define ETHERM_DATAPORT		0x200	/* MEMC */
#define ETHERM_NS8390		0x800	/* MEMC */
#define ETHERM_CTRLPORT		0x23c	/* MEMC */

#define ETHERM_TX_START_PAGE	64
#define ETHERM_STOP_PAGE	127

/* ------------------------------------------------------------------------ */

#define etherh_priv(dev) \
 ((struct etherh_priv *)(((char *)netdev_priv(dev)) + sizeof(struct ei_device)))

static inline void etherh_set_ctrl(struct etherh_priv *eh, unsigned char mask)
{
	unsigned char ctrl = eh->ctrl | mask;
	eh->ctrl = ctrl;
	writeb(ctrl, eh->ctrl_port);
}

static inline void etherh_clr_ctrl(struct etherh_priv *eh, unsigned char mask)
{
	unsigned char ctrl = eh->ctrl & ~mask;
	eh->ctrl = ctrl;
	writeb(ctrl, eh->ctrl_port);
}

static inline unsigned int etherh_get_stat(struct etherh_priv *eh)
{
	return readb(eh->ctrl_port);
}




static void etherh_irq_enable(ecard_t *ec, int irqnr)
{
	struct etherh_priv *eh = ec->irq_data;

	etherh_set_ctrl(eh, ETHERH_CP_IE);
}

static void etherh_irq_disable(ecard_t *ec, int irqnr)
{
	struct etherh_priv *eh = ec->irq_data;

	etherh_clr_ctrl(eh, ETHERH_CP_IE);
}

static expansioncard_ops_t etherh_ops = {
	.irqenable	= etherh_irq_enable,
	.irqdisable	= etherh_irq_disable,
};




static void
etherh_setif(struct net_device *dev)
{
	struct ei_device *ei_local = netdev_priv(dev);
	unsigned long flags;
	void __iomem *addr;

	local_irq_save(flags);

	/* set the interface type */
	switch (etherh_priv(dev)->id) {
	case PROD_I3_ETHERLAN600:
	case PROD_I3_ETHERLAN600A:
		addr = (void *)dev->base_addr + EN0_RCNTHI;

		switch (dev->if_port) {
		case IF_PORT_10BASE2:
			writeb((readb(addr) & 0xf8) | 1, addr);
			break;
		case IF_PORT_10BASET:
			writeb((readb(addr) & 0xf8), addr);
			break;
		}
		break;

	case PROD_I3_ETHERLAN500:
		switch (dev->if_port) {
		case IF_PORT_10BASE2:
			etherh_clr_ctrl(etherh_priv(dev), ETHERH_CP_IF);
			break;

		case IF_PORT_10BASET:
			etherh_set_ctrl(etherh_priv(dev), ETHERH_CP_IF);
			break;
		}
		break;

	default:
		break;
	}

	local_irq_restore(flags);
}

static int
etherh_getifstat(struct net_device *dev)
{
	struct ei_device *ei_local = netdev_priv(dev);
	void __iomem *addr;
	int stat = 0;

	switch (etherh_priv(dev)->id) {
	case PROD_I3_ETHERLAN600:
	case PROD_I3_ETHERLAN600A:
		addr = (void *)dev->base_addr + EN0_RCNTHI;
		switch (dev->if_port) {
		case IF_PORT_10BASE2:
			stat = 1;
			break;
		case IF_PORT_10BASET:
			stat = readb(addr) & 4;
			break;
		}
		break;

	case PROD_I3_ETHERLAN500:
		switch (dev->if_port) {
		case IF_PORT_10BASE2:
			stat = 1;
			break;
		case IF_PORT_10BASET:
			stat = etherh_get_stat(etherh_priv(dev)) & ETHERH_CP_HEARTBEAT;
			break;
		}
		break;

	default:
		stat = 0;
		break;
	}

	return stat != 0;
}

/*
 * Configure the interface.  Note that we ignore the other
 * parts of ifmap, since its mostly meaningless for this driver.
 */
static int etherh_set_config(struct net_device *dev, struct ifmap *map)
{
	switch (map->port) {
	case IF_PORT_10BASE2:
	case IF_PORT_10BASET:
		/*
		 * If the user explicitly sets the interface
		 * media type, turn off automedia detection.
		 */
		dev->flags &= ~IFF_AUTOMEDIA;
		dev->if_port = map->port;
		break;

	default:
		return -EINVAL;
	}

	etherh_setif(dev);

	return 0;
}

/*
 * Reset the 8390 (hard reset).  Note that we can't actually do this.
 */
static void
etherh_reset(struct net_device *dev)
{
	struct ei_device *ei_local = netdev_priv(dev);
	void __iomem *addr = (void *)dev->base_addr;

	writeb(E8390_NODMA+E8390_PAGE0+E8390_STOP, addr);

	/*
	 * See if we need to change the interface type.
	 * Note that we use 'interface_num' as a flag
	 * to indicate that we need to change the media.
	 */
	if (dev->flags & IFF_AUTOMEDIA && ei_local->interface_num) {
		ei_local->interface_num = 0;

		if (dev->if_port == IF_PORT_10BASET)
			dev->if_port = IF_PORT_10BASE2;
		else
			dev->if_port = IF_PORT_10BASET;

		etherh_setif(dev);
	}
}

/*
 * Write a block of data out to the 8390
 */
static void
etherh_block_output (struct net_device *dev, int count, const unsigned char *buf, int start_page)
{
	struct ei_device *ei_local = netdev_priv(dev);
	unsigned long dma_start;
	void __iomem *dma_base, *addr;

	if (ei_local->dmaing) {
		printk(KERN_ERR "%s: DMAing conflict in etherh_block_input: "
			" DMAstat %d irqlock %d\n", dev->name,
			ei_local->dmaing, ei_local->irqlock);
		return;
	}

	/*
	 * Make sure we have a round number of bytes if we're in word mode.
	 */
	if (count & 1 && ei_local->word16)
		count++;

	ei_local->dmaing = 1;

	addr = (void *)dev->base_addr;
	dma_base = etherh_priv(dev)->dma_base;

	count = (count + 1) & ~1;
	writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);

	writeb (0x42, addr + EN0_RCNTLO);
	writeb (0x00, addr + EN0_RCNTHI);
	writeb (0x42, addr + EN0_RSARLO);
	writeb (0x00, addr + EN0_RSARHI);
	writeb (E8390_RREAD | E8390_START, addr + E8390_CMD);

	udelay (1);

	writeb (ENISR_RDC, addr + EN0_ISR);
	writeb (count, addr + EN0_RCNTLO);
	writeb (count >> 8, addr + EN0_RCNTHI);
	writeb (0, addr + EN0_RSARLO);
	writeb (start_page, addr + EN0_RSARHI);
	writeb (E8390_RWRITE | E8390_START, addr + E8390_CMD);

	if (ei_local->word16)
		writesw (dma_base, buf, count >> 1);
	else
		writesb (dma_base, buf, count);

	dma_start = jiffies;

	while ((readb (addr + EN0_ISR) & ENISR_RDC) == 0)
		if (time_after(jiffies, dma_start + 2*HZ/100)) { /* 20ms */
			printk(KERN_ERR "%s: timeout waiting for TX RDC\n",
				dev->name);
			etherh_reset (dev);
			NS8390_init (dev, 1);
			break;
		}

	writeb (ENISR_RDC, addr + EN0_ISR);
	ei_local->dmaing = 0;
}

/*
 * Read a block of data from the 8390
 */
static void
etherh_block_input (struct net_device *dev, int count, struct sk_buff *skb, int ring_offset)
{
	struct ei_device *ei_local = netdev_priv(dev);
	unsigned char *buf;
	void __iomem *dma_base, *addr;

	if (ei_local->dmaing) {
		printk(KERN_ERR "%s: DMAing conflict in etherh_block_input: "
			" DMAstat %d irqlock %d\n", dev->name,
			ei_local->dmaing, ei_local->irqlock);
		return;
	}

	ei_local->dmaing = 1;

	addr = (void *)dev->base_addr;
	dma_base = etherh_priv(dev)->dma_base;

	buf = skb->data;
	writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
	writeb (count, addr + EN0_RCNTLO);
	writeb (count >> 8, addr + EN0_RCNTHI);
	writeb (ring_offset, addr + EN0_RSARLO);
	writeb (ring_offset >> 8, addr + EN0_RSARHI);
	writeb (E8390_RREAD | E8390_START, addr + E8390_CMD);

	if (ei_local->word16) {
		readsw (dma_base, buf, count >> 1);
		if (count & 1)
			buf[count - 1] = readb (dma_base);
	} else
		readsb (dma_base, buf, count);

	writeb (ENISR_RDC, addr + EN0_ISR);
	ei_local->dmaing = 0;
}

/*
 * Read a header from the 8390
 */
static void
etherh_get_header (struct net_device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
{
	struct ei_device *ei_local = netdev_priv(dev);
	void __iomem *dma_base, *addr;

	if (ei_local->dmaing) {
		printk(KERN_ERR "%s: DMAing conflict in etherh_get_header: "
			" DMAstat %d irqlock %d\n", dev->name,
			ei_local->dmaing, ei_local->irqlock);
		return;
	}

	ei_local->dmaing = 1;

	addr = (void *)dev->base_addr;
	dma_base = etherh_priv(dev)->dma_base;

	writeb (E8390_NODMA | E8390_PAGE0 | E8390_START, addr + E8390_CMD);
	writeb (sizeof (*hdr), addr + EN0_RCNTLO);
	writeb (0, addr + EN0_RCNTHI);
	writeb (0, addr + EN0_RSARLO);
	writeb (ring_page, addr + EN0_RSARHI);
	writeb (E8390_RREAD | E8390_START, addr + E8390_CMD);

	if (ei_local->word16)
		readsw (dma_base, hdr, sizeof (*hdr) >> 1);
	else
		readsb (dma_base, hdr, sizeof (*hdr));

	writeb (ENISR_RDC, addr + EN0_ISR);
	ei_local->dmaing = 0;
}

/*
 * Open/initialize the board.  This is called (in the current kernel)
 * sometime after booting when the 'ifconfig' program is run.
 *
 * This routine should set everything up anew at each open, even
 * registers that "should" only need to be set once at boot, so that
 * there is non-reboot way to recover if something goes wrong.
 */
static int
etherh_open(struct net_device *dev)
{
	struct ei_device *ei_local = netdev_priv(dev);

	if (!is_valid_ether_addr(dev->dev_addr)) {
		printk(KERN_WARNING "%s: invalid ethernet MAC address\n",
			dev->name);
		return -EINVAL;
	}

	if (request_irq(dev->irq, ei_interrupt, 0, dev->name, dev))
		return -EAGAIN;

	/*
	 * Make sure that we aren't going to change the
	 * media type on the next reset - we are about to
	 * do automedia manually now.
	 */
	ei_local->interface_num = 0;

	/*
	 * If we are doing automedia detection, do it now.
	 * This is more reliable than the 8390's detection.
	 */
	if (dev->flags & IFF_AUTOMEDIA) {
		dev->if_port = IF_PORT_10BASET;
		etherh_setif(dev);
		mdelay(1);
		if (!etherh_getifstat(dev)) {
			dev->if_port = IF_PORT_10BASE2;
			etherh_setif(dev);
		}
	} else
		etherh_setif(dev);

	etherh_reset(dev);
	ei_open(dev);

	return 0;
}

/*
 * The inverse routine to etherh_open().
 */
static int
etherh_close(struct net_device *dev)
{
	ei_close (dev);
	free_irq (dev->irq, dev);
	return 0;
}

/*
 * Initialisation
 */

static void __init etherh_banner(void)
{
	static int version_printed;

	if (net_debug && version_printed++ == 0)
		printk(KERN_INFO "%s", version);
}

/*
 * Read the ethernet address string from the on board rom.
 * This is an ascii string...
 */
static int __init etherh_addr(char *addr, struct expansion_card *ec)
{
	struct in_chunk_dir cd;
	char *s;
	
	if (!ecard_readchunk(&cd, ec, 0xf5, 0)) {
		printk(KERN_ERR "%s: unable to read podule description string\n",
		       ec->dev.bus_id);
		goto no_addr;
	}

	s = strchr(cd.d.string, '(');
	if (s) {
		int i;

		for (i = 0; i < 6; i++) {
			addr[i] = simple_strtoul(s + 1, &s, 0x10);
			if (*s != (i == 5? ')' : ':'))
				break;
		}

		if (i == 6)
			return 0;
	}

	printk(KERN_ERR "%s: unable to parse MAC address: %s\n",
	       ec->dev.bus_id, cd.d.string);

 no_addr:
	return -ENODEV;
}

/*
 * Create an ethernet address from the system serial number.
 */
static int __init etherm_addr(char *addr)
{
	unsigned int serial;

	if (system_serial_low == 0 && system_serial_high == 0)
		return -ENODEV;

	serial = system_serial_low | system_serial_high;

	addr[0] = 0;
	addr[1] = 0;
	addr[2] = 0xa4;
	addr[3] = 0x10 + (serial >> 24);
	addr[4] = serial >> 16;
	addr[5] = serial >> 8;
	return 0;
}

static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
	strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
	strlcpy(info->version, DRV_VERSION, sizeof(info->version));
	strlcpy(info->bus_info, dev->class_dev.dev->bus_id,
		sizeof(info->bus_info));
}

static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	cmd->supported	= etherh_priv(dev)->supported;
	cmd->speed	= SPEED_10;
	cmd->duplex	= DUPLEX_HALF;
	cmd->port	= dev->if_port == IF_PORT_10BASET ? PORT_TP : PORT_BNC;
	cmd->autoneg	= dev->flags & IFF_AUTOMEDIA ? AUTONEG_ENABLE : AUTONEG_DISABLE;
	return 0;
}

static int etherh_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	switch (cmd->autoneg) {
	case AUTONEG_ENABLE:
		dev->flags |= IFF_AUTOMEDIA;
		break;

	case AUTONEG_DISABLE:
		switch (cmd->port) {
		case PORT_TP:
			dev->if_port = IF_PORT_10BASET;
			break;

		case PORT_BNC:
			dev->if_port = IF_PORT_10BASE2;
			break;

		default:
			return -EINVAL;
		}
		dev->flags &= ~IFF_AUTOMEDIA;
		break;

	default:
		return -EINVAL;
	}

	etherh_setif(dev);

	return 0;
}

static const struct ethtool_ops etherh_ethtool_ops = {
	.get_settings	= etherh_get_settings,
	.set_settings	= etherh_set_settings,
	.get_drvinfo	= etherh_get_drvinfo,
};

static u32 etherh_regoffsets[16];
static u32 etherm_regoffsets[16];

static int __init
etherh_probe(struct expansion_card *ec, const struct ecard_id *id)
{
	const struct etherh_data *data = id->data;
	struct ei_device *ei_local;
	struct net_device *dev;
	struct etherh_priv *eh;
	int i, ret;

	etherh_banner();

	ret = ecard_request_resources(ec);
	if (ret)
		goto out;

	dev = __alloc_ei_netdev(sizeof(struct etherh_priv));
	if (!dev) {
		ret = -ENOMEM;
		goto release;
	}

	SET_MODULE_OWNER(dev);
	SET_NETDEV_DEV(dev, &ec->dev);

	dev->open		= etherh_open;
	dev->stop		= etherh_close;
	dev->set_config		= etherh_set_config;
	dev->irq		= ec->irq;
	dev->ethtool_ops	= &etherh_ethtool_ops;

	if (data->supported & SUPPORTED_Autoneg)
		dev->flags |= IFF_AUTOMEDIA;
	if (data->supported & SUPPORTED_TP) {
		dev->flags |= IFF_PORTSEL;
		dev->if_port = IF_PORT_10BASET;
	} else if (data->supported & SUPPORTED_BNC) {
		dev->flags |= IFF_PORTSEL;
		dev->if_port = IF_PORT_10BASE2;
	} else
		dev->if_port = IF_PORT_UNKNOWN;

	eh = etherh_priv(dev);
	eh->supported		= data->supported;
	eh->ctrl		= 0;
	eh->id			= ec->cid.product;
	eh->memc		= ioremap(ecard_resource_start(ec, ECARD_RES_MEMC), PAGE_SIZE);
	if (!eh->memc) {
		ret = -ENOMEM;
		goto free;
	}

	eh->ctrl_port = eh->memc;
	if (data->ctrl_ioc) {
		eh->ioc_fast = ioremap(ecard_resource_start(ec, ECARD_RES_IOCFAST), PAGE_SIZE);
		if (!eh->ioc_fast) {
			ret = -ENOMEM;
			goto free;
		}
		eh->ctrl_port = eh->ioc_fast;
	}

	dev->base_addr = (unsigned long)eh->memc + data->ns8390_offset;
	eh->dma_base = eh->memc + data->dataport_offset;
	eh->ctrl_port += data->ctrlport_offset;

	/*
	 * IRQ and control port handling - only for non-NIC slot cards.
	 */
	if (ec->slot_no != 8) {
		ec->ops		= &etherh_ops;
		ec->irq_data	= eh;
	} else {
		/*
		 * If we're in the NIC slot, make sure the IRQ is enabled
		 */
		etherh_set_ctrl(eh, ETHERH_CP_IE);
	}

	ei_local = netdev_priv(dev);
	spin_lock_init(&ei_local->page_lock);

	if (ec->cid.product == PROD_ANT_ETHERM) {
		etherm_addr(dev->dev_addr);
		ei_local->reg_offset = etherm_regoffsets;
	} else {
		etherh_addr(dev->dev_addr, ec);
		ei_local->reg_offset = etherh_regoffsets;
	}

	ei_local->name          = dev->name;
	ei_local->word16        = 1;
	ei_local->tx_start_page = data->tx_start_page;
	ei_local->rx_start_page = ei_local->tx_start_page + TX_PAGES;
	ei_local->stop_page     = data->stop_page;
	ei_local->reset_8390    = etherh_reset;
	ei_local->block_input   = etherh_block_input;
	ei_local->block_output  = etherh_block_output;
	ei_local->get_8390_hdr  = etherh_get_header;
	ei_local->interface_num = 0;

	etherh_reset(dev);
	NS8390_init(dev, 0);

	ret = register_netdev(dev);
	if (ret)
		goto free;

	printk(KERN_INFO "%s: %s in slot %d, ",
		dev->name, data->name, ec->slot_no);

	for (i = 0; i < 6; i++)
		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');

	ecard_set_drvdata(ec, dev);

	return 0;

 free:
	if (eh->ioc_fast)
		iounmap(eh->ioc_fast);
	if (eh->memc)
		iounmap(eh->memc);
	free_netdev(dev);
 release:
	ecard_release_resources(ec);
 out:
	return ret;
}

static void __devexit etherh_remove(struct expansion_card *ec)
{
	struct net_device *dev = ecard_get_drvdata(ec);
	struct etherh_priv *eh = etherh_priv(dev);

	ecard_set_drvdata(ec, NULL);

	unregister_netdev(dev);
	ec->ops = NULL;

	if (eh->ioc_fast)
		iounmap(eh->ioc_fast);
	iounmap(eh->memc);

	free_netdev(dev);

	ecard_release_resources(ec);
}

static struct etherh_data etherm_data = {
	.ns8390_offset		= ETHERM_NS8390,
	.dataport_offset	= ETHERM_NS8390 + ETHERM_DATAPORT,
	.ctrlport_offset	= ETHERM_NS8390 + ETHERM_CTRLPORT,
	.name			= "ANT EtherM",
	.supported		= SUPPORTED_10baseT_Half,
	.tx_start_page		= ETHERM_TX_START_PAGE,
	.stop_page		= ETHERM_STOP_PAGE,
};

static struct etherh_data etherlan500_data = {
	.ns8390_offset		= ETHERH500_NS8390,
	.dataport_offset	= ETHERH500_NS8390 + ETHERH500_DATAPORT,
	.ctrlport_offset	= ETHERH500_CTRLPORT,
	.ctrl_ioc		= 1,
	.name			= "i3 EtherH 500",
	.supported		= SUPPORTED_10baseT_Half,
	.tx_start_page		= ETHERH_TX_START_PAGE,
	.stop_page		= ETHERH_STOP_PAGE,
};

static struct etherh_data etherlan600_data = {
	.ns8390_offset		= ETHERH600_NS8390,
	.dataport_offset	= ETHERH600_NS8390 + ETHERH600_DATAPORT,
	.ctrlport_offset	= ETHERH600_NS8390 + ETHERH600_CTRLPORT,
	.name			= "i3 EtherH 600",
	.supported		= SUPPORTED_10baseT_Half | SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_Autoneg,
	.tx_start_page		= ETHERH_TX_START_PAGE,
	.stop_page		= ETHERH_STOP_PAGE,
};

static struct etherh_data etherlan600a_data = {
	.ns8390_offset		= ETHERH600_NS8390,
	.dataport_offset	= ETHERH600_NS8390 + ETHERH600_DATAPORT,
	.ctrlport_offset	= ETHERH600_NS8390 + ETHERH600_CTRLPORT,
	.name			= "i3 EtherH 600A",
	.supported		= SUPPORTED_10baseT_Half | SUPPORTED_TP | SUPPORTED_BNC | SUPPORTED_Autoneg,
	.tx_start_page		= ETHERH_TX_START_PAGE,
	.stop_page		= ETHERH_STOP_PAGE,
};

static const struct ecard_id etherh_ids[] = {
	{ MANU_ANT, PROD_ANT_ETHERM,      &etherm_data       },
	{ MANU_I3,  PROD_I3_ETHERLAN500,  &etherlan500_data  },
	{ MANU_I3,  PROD_I3_ETHERLAN600,  &etherlan600_data  },
	{ MANU_I3,  PROD_I3_ETHERLAN600A, &etherlan600a_data },
	{ 0xffff,   0xffff }
};

static struct ecard_driver etherh_driver = {
	.probe		= etherh_probe,
	.remove		= __devexit_p(etherh_remove),
	.id_table	= etherh_ids,
	.drv = {
		.name	= DRV_NAME,
	},
};

static int __init etherh_init(void)
{
	int i;

	for (i = 0; i < 16; i++) {
		etherh_regoffsets[i] = i << 2;
		etherm_regoffsets[i] = i << 5;
	}

	return ecard_register_driver(&etherh_driver);
}

static void __exit etherh_exit(void)
{
	ecard_remove_driver(&etherh_driver);
}

module_init(etherh_init);
module_exit(etherh_exit);
