/* hplance.c  : the  Linux/hp300/lance ethernet driver
 *
 * Copyright (C) 05/1998 Peter Maydell <pmaydell@chiark.greenend.org.uk>
 * Based on the Sun Lance driver and the NetBSD HP Lance driver
 * Uses the generic 7990.c LANCE code.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/interrupt.h>
#include <linux/ioport.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/errno.h>
/* Used for the temporal inet entries and routing */
#include <linux/socket.h>
#include <linux/route.h>
#include <linux/dio.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>

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

#include "hplance.h"

/* We have 16834 bytes of RAM for the init block and buffers. This places
 * an upper limit on the number of buffers we can use. NetBSD uses 8 Rx
 * buffers and 2 Tx buffers.
 */
#define LANCE_LOG_TX_BUFFERS 1
#define LANCE_LOG_RX_BUFFERS 3

#include "7990.h"                                 /* use generic LANCE code */

/* Our private data structure */
struct hplance_private {
	struct lance_private lance;
};

/* function prototypes... This is easy because all the grot is in the
 * generic LANCE support. All we have to support is probing for boards,
 * plus board-specific init, open and close actions.
 * Oh, and we need to tell the generic code how to read and write LANCE registers...
 */
static int __devinit hplance_init_one(struct dio_dev *d,
				const struct dio_device_id *ent);
static void __devinit hplance_init(struct net_device *dev,
				struct dio_dev *d);
static void __devexit hplance_remove_one(struct dio_dev *d);
static void hplance_writerap(void *priv, unsigned short value);
static void hplance_writerdp(void *priv, unsigned short value);
static unsigned short hplance_readrdp(void *priv);
static int hplance_open(struct net_device *dev);
static int hplance_close(struct net_device *dev);

static struct dio_device_id hplance_dio_tbl[] = {
	{ DIO_ID_LAN },
	{ 0 }
};

static struct dio_driver hplance_driver = {
	.name      = "hplance",
	.id_table  = hplance_dio_tbl,
	.probe     = hplance_init_one,
	.remove    = __devexit_p(hplance_remove_one),
};

static const struct net_device_ops hplance_netdev_ops = {
	.ndo_open		= hplance_open,
	.ndo_stop		= hplance_close,
	.ndo_start_xmit		= lance_start_xmit,
	.ndo_set_multicast_list	= lance_set_multicast,
	.ndo_change_mtu		= eth_change_mtu,
	.ndo_validate_addr	= eth_validate_addr,
	.ndo_set_mac_address	= eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
	.ndo_poll_controller	= lance_poll,
#endif
};

/* Find all the HP Lance boards and initialise them... */
static int __devinit hplance_init_one(struct dio_dev *d,
				const struct dio_device_id *ent)
{
	struct net_device *dev;
	int err = -ENOMEM;
	int i;

	dev = alloc_etherdev(sizeof(struct hplance_private));
	if (!dev)
		goto out;

	err = -EBUSY;
	if (!request_mem_region(dio_resource_start(d),
				dio_resource_len(d), d->name))
		goto out_free_netdev;

	hplance_init(dev, d);
	err = register_netdev(dev);
	if (err)
		goto out_release_mem_region;

	dio_set_drvdata(d, dev);

	printk(KERN_INFO "%s: %s; select code %d, addr %2.2x", dev->name, d->name, d->scode, dev->dev_addr[0]);

	for (i=1; i<6; i++) {
		printk(":%2.2x", dev->dev_addr[i]);
	}

	printk(", irq %d\n", d->ipl);

	return 0;

 out_release_mem_region:
	release_mem_region(dio_resource_start(d), dio_resource_len(d));
 out_free_netdev:
	free_netdev(dev);
 out:
	return err;
}

static void __devexit hplance_remove_one(struct dio_dev *d)
{
	struct net_device *dev = dio_get_drvdata(d);

	unregister_netdev(dev);
	release_mem_region(dio_resource_start(d), dio_resource_len(d));
	free_netdev(dev);
}

/* Initialise a single lance board at the given DIO device */
static void __init hplance_init(struct net_device *dev, struct dio_dev *d)
{
        unsigned long va = (d->resource.start + DIO_VIRADDRBASE);
        struct hplance_private *lp;
        int i;

        /* reset the board */
        out_8(va+DIO_IDOFF, 0xff);
        udelay(100);                              /* ariba! ariba! udelay! udelay! */

        /* Fill the dev fields */
        dev->base_addr = va;
        dev->netdev_ops = &hplance_netdev_ops;
        dev->dma = 0;

        for (i=0; i<6; i++) {
                /* The NVRAM holds our ethernet address, one nibble per byte,
                 * at bytes NVRAMOFF+1,3,5,7,9...
                 */
                dev->dev_addr[i] = ((in_8(va + HPLANCE_NVRAMOFF + i*4 + 1) & 0xF) << 4)
                        | (in_8(va + HPLANCE_NVRAMOFF + i*4 + 3) & 0xF);
        }

        lp = netdev_priv(dev);
        lp->lance.name = (char*)d->name;                /* discards const, shut up gcc */
        lp->lance.base = va;
        lp->lance.init_block = (struct lance_init_block *)(va + HPLANCE_MEMOFF); /* CPU addr */
        lp->lance.lance_init_block = NULL;              /* LANCE addr of same RAM */
        lp->lance.busmaster_regval = LE_C3_BSWP;        /* we're bigendian */
        lp->lance.irq = d->ipl;
        lp->lance.writerap = hplance_writerap;
        lp->lance.writerdp = hplance_writerdp;
        lp->lance.readrdp = hplance_readrdp;
        lp->lance.lance_log_rx_bufs = LANCE_LOG_RX_BUFFERS;
        lp->lance.lance_log_tx_bufs = LANCE_LOG_TX_BUFFERS;
        lp->lance.rx_ring_mod_mask = RX_RING_MOD_MASK;
        lp->lance.tx_ring_mod_mask = TX_RING_MOD_MASK;
}

/* This is disgusting. We have to check the DIO status register for ack every
 * time we read or write the LANCE registers.
 */
static void hplance_writerap(void *priv, unsigned short value)
{
	struct lance_private *lp = (struct lance_private *)priv;
	do {
		out_be16(lp->base + HPLANCE_REGOFF + LANCE_RAP, value);
	} while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
}

static void hplance_writerdp(void *priv, unsigned short value)
{
	struct lance_private *lp = (struct lance_private *)priv;
	do {
		out_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP, value);
	} while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
}

static unsigned short hplance_readrdp(void *priv)
{
	struct lance_private *lp = (struct lance_private *)priv;
	__u16 value;
	do {
		value = in_be16(lp->base + HPLANCE_REGOFF + LANCE_RDP);
	} while ((in_8(lp->base + HPLANCE_STATUS) & LE_ACK) == 0);
	return value;
}

static int hplance_open(struct net_device *dev)
{
        int status;
        struct lance_private *lp = netdev_priv(dev);

        status = lance_open(dev);                 /* call generic lance open code */
        if (status)
                return status;
        /* enable interrupts at board level. */
        out_8(lp->base + HPLANCE_STATUS, LE_IE);

        return 0;
}

static int hplance_close(struct net_device *dev)
{
        struct lance_private *lp = netdev_priv(dev);

        out_8(lp->base + HPLANCE_STATUS, 0);	/* disable interrupts at boardlevel */
        lance_close(dev);
        return 0;
}

static int __init hplance_init_module(void)
{
	return dio_register_driver(&hplance_driver);
}

static void __exit hplance_cleanup_module(void)
{
        dio_unregister_driver(&hplance_driver);
}

module_init(hplance_init_module);
module_exit(hplance_cleanup_module);

MODULE_LICENSE("GPL");
