/*
 *  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/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/in.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/ecard.h>
#include <asm/io.h>
#include <asm/system_info.h>

#define EI_SHIFT(x)	(ei_local->reg_offset[x])

#define ei_inb(_p)	 readb((void __iomem *)_p)
#define ei_outb(_v,_p)	 writeb(_v,(void __iomem *)_p)
#define ei_inb_p(_p)	 readb((void __iomem *)_p)
#define ei_outb_p(_v,_p) writeb(_v,(void __iomem *)_p)

#define NET_DEBUG  0
#define DEBUG_INIT 2

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

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

#include "lib8390.c"

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");

#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 __iomem *)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 __iomem *)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 __iomem *)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 __iomem *)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 __iomem *)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 __iomem *)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 __devinit 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",
		       dev_name(&ec->dev));
		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",
	       dev_name(&ec->dev), 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_name(dev->dev.parent),
		sizeof(info->bus_info));
}

static int etherh_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
{
	cmd->supported	= etherh_priv(dev)->supported;
	ethtool_cmd_speed_set(cmd, 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,
	.get_ts_info	= ethtool_op_get_ts_info,
};

static const struct net_device_ops etherh_netdev_ops = {
	.ndo_open		= etherh_open,
	.ndo_stop		= etherh_close,
	.ndo_set_config		= etherh_set_config,
	.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 u32 etherh_regoffsets[16];
static u32 etherm_regoffsets[16];

static int __devinit
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 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_NETDEV_DEV(dev, &ec->dev);

	dev->netdev_ops		= &etherh_netdev_ops;
	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		= ecardm_iomap(ec, ECARD_RES_MEMC, 0, PAGE_SIZE);
	if (!eh->memc) {
		ret = -ENOMEM;
		goto free;
	}

	eh->ctrl_port = eh->memc;
	if (data->ctrl_ioc) {
		eh->ioc_fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 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) {
		ecard_setirq(ec, &etherh_ops, 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, %pM\n",
		dev->name, data->name, ec->slot_no, dev->dev_addr);

	ecard_set_drvdata(ec, dev);

	return 0;

 free:
	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);

	ecard_set_drvdata(ec, NULL);

	unregister_netdev(dev);

	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);
