/*
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 */

#define DEBUG

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/sched.h>
#include <linux/etherdevice.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <asm/io.h>
#include <asm/mips-boards/simint.h>

#include "mipsnet.h"		/* actual device IO mapping */

#define MIPSNET_VERSION "2005-06-20"

#define mipsnet_reg_address(dev, field) (dev->base_addr + field_offset(field))

struct mipsnet_priv {
	struct net_device_stats stats;
};

static struct platform_device *mips_plat_dev;

static char mipsnet_string[] = "mipsnet";

/*
 * Copy data from the MIPSNET rx data port
 */
static int ioiocpy_frommipsnet(struct net_device *dev, unsigned char *kdata,
			int len)
{
	uint32_t available_len = inl(mipsnet_reg_address(dev, rxDataCount));
	if (available_len < len)
		return -EFAULT;

	for (; len > 0; len--, kdata++) {
		*kdata = inb(mipsnet_reg_address(dev, rxDataBuffer));
	}

	return inl(mipsnet_reg_address(dev, rxDataCount));
}

static inline ssize_t mipsnet_put_todevice(struct net_device *dev,
	struct sk_buff *skb)
{
	int count_to_go = skb->len;
	char *buf_ptr = skb->data;
	struct mipsnet_priv *mp = netdev_priv(dev);

	pr_debug("%s: %s(): telling MIPSNET txDataCount(%d)\n",
	         dev->name, __FUNCTION__, skb->len);

	outl(skb->len, mipsnet_reg_address(dev, txDataCount));

	pr_debug("%s: %s(): sending data to MIPSNET txDataBuffer(%d)\n",
	         dev->name, __FUNCTION__, skb->len);

	for (; count_to_go; buf_ptr++, count_to_go--) {
		outb(*buf_ptr, mipsnet_reg_address(dev, txDataBuffer));
	}

	mp->stats.tx_packets++;
	mp->stats.tx_bytes += skb->len;

	return skb->len;
}

static int mipsnet_xmit(struct sk_buff *skb, struct net_device *dev)
{
	pr_debug("%s:%s(): transmitting %d bytes\n",
	         dev->name, __FUNCTION__, skb->len);

	/* Only one packet at a time. Once TXDONE interrupt is serviced, the
	 * queue will be restarted.
	 */
	netif_stop_queue(dev);
	mipsnet_put_todevice(dev, skb);

	return 0;
}

static inline ssize_t mipsnet_get_fromdev(struct net_device *dev, size_t count)
{
	struct sk_buff *skb;
	size_t len = count;
	struct mipsnet_priv *mp = netdev_priv(dev);

	if (!(skb = alloc_skb(len + 2, GFP_KERNEL))) {
		mp->stats.rx_dropped++;
		return -ENOMEM;
	}

	skb_reserve(skb, 2);
	if (ioiocpy_frommipsnet(dev, skb_put(skb, len), len))
		return -EFAULT;

	skb->dev = dev;
	skb->protocol = eth_type_trans(skb, dev);
	skb->ip_summed = CHECKSUM_UNNECESSARY;

	pr_debug("%s:%s(): pushing RXed data to kernel\n",
	         dev->name, __FUNCTION__);
	netif_rx(skb);

	mp->stats.rx_packets++;
	mp->stats.rx_bytes += len;

	return count;
}

static irqreturn_t
mipsnet_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
	struct net_device *dev = dev_id;

	irqreturn_t retval = IRQ_NONE;
	uint64_t interruptFlags;

	if (irq == dev->irq) {
		pr_debug("%s:%s(): irq %d for device\n",
		         dev->name, __FUNCTION__, irq);

		retval = IRQ_HANDLED;

		interruptFlags =
		    inl(mipsnet_reg_address(dev, interruptControl));
		pr_debug("%s:%s(): intCtl=0x%016llx\n", dev->name,
		         __FUNCTION__, interruptFlags);

		if (interruptFlags & MIPSNET_INTCTL_TXDONE) {
			pr_debug("%s:%s(): got TXDone\n",
			         dev->name, __FUNCTION__);
			outl(MIPSNET_INTCTL_TXDONE,
			     mipsnet_reg_address(dev, interruptControl));
			// only one packet at a time, we are done.
			netif_wake_queue(dev);
		} else if (interruptFlags & MIPSNET_INTCTL_RXDONE) {
			pr_debug("%s:%s(): got RX data\n",
			         dev->name, __FUNCTION__);
			mipsnet_get_fromdev(dev,
			            inl(mipsnet_reg_address(dev, rxDataCount)));
			pr_debug("%s:%s(): clearing RX int\n",
			         dev->name, __FUNCTION__);
			outl(MIPSNET_INTCTL_RXDONE,
			     mipsnet_reg_address(dev, interruptControl));

		} else if (interruptFlags & MIPSNET_INTCTL_TESTBIT) {
			pr_debug("%s:%s(): got test interrupt\n",
			         dev->name, __FUNCTION__);
			// TESTBIT is cleared on read.
			//    And takes effect after a write with 0
			outl(0, mipsnet_reg_address(dev, interruptControl));
		} else {
			pr_debug("%s:%s(): no valid fags 0x%016llx\n",
			         dev->name, __FUNCTION__, interruptFlags);
			// Maybe shared IRQ, just ignore, no clearing.
			retval = IRQ_NONE;
		}

	} else {
		printk(KERN_INFO "%s: %s(): irq %d for unknown device\n",
		       dev->name, __FUNCTION__, irq);
		retval = IRQ_NONE;
	}
	return retval;
}				//mipsnet_interrupt()

static int mipsnet_open(struct net_device *dev)
{
	int err;
	pr_debug("%s: mipsnet_open\n", dev->name);

	err = request_irq(dev->irq, &mipsnet_interrupt,
			  SA_SHIRQ, dev->name, (void *) dev);

	if (err) {
		pr_debug("%s: %s(): can't get irq %d\n",
		         dev->name, __FUNCTION__, dev->irq);
		release_region(dev->base_addr, MIPSNET_IO_EXTENT);
		return err;
	}

	pr_debug("%s: %s(): got IO region at 0x%04lx and irq %d for dev.\n",
	         dev->name, __FUNCTION__, dev->base_addr, dev->irq);


	netif_start_queue(dev);

	// test interrupt handler
	outl(MIPSNET_INTCTL_TESTBIT,
	     mipsnet_reg_address(dev, interruptControl));


	return 0;
}

static int mipsnet_close(struct net_device *dev)
{
	pr_debug("%s: %s()\n", dev->name, __FUNCTION__);
	netif_stop_queue(dev);
	return 0;
}

static struct net_device_stats *mipsnet_get_stats(struct net_device *dev)
{
	struct mipsnet_priv *mp = netdev_priv(dev);

	return &mp->stats;
}

static void mipsnet_set_mclist(struct net_device *dev)
{
	// we don't do anything
	return;
}

static int __init mipsnet_probe(struct device *dev)
{
	struct net_device *netdev;
	int err;

	netdev = alloc_etherdev(sizeof(struct mipsnet_priv));
	if (!netdev) {
		err = -ENOMEM;
		goto out;
	}

	dev_set_drvdata(dev, netdev);

	netdev->open			= mipsnet_open;
	netdev->stop			= mipsnet_close;
	netdev->hard_start_xmit		= mipsnet_xmit;
	netdev->get_stats		= mipsnet_get_stats;
	netdev->set_multicast_list	= mipsnet_set_mclist;

	/*
	 * TODO: probe for these or load them from PARAM
	 */
	netdev->base_addr = 0x4200;
	netdev->irq = MIPSCPU_INT_BASE + MIPSCPU_INT_MB0 +
	              inl(mipsnet_reg_address(netdev, interruptInfo));

	// Get the io region now, get irq on open()
	if (!request_region(netdev->base_addr, MIPSNET_IO_EXTENT, "mipsnet")) {
		pr_debug("%s: %s(): IO region {start: 0x%04lux, len: %d} "
		         "for dev is not availble.\n", netdev->name,
		         __FUNCTION__, netdev->base_addr, MIPSNET_IO_EXTENT);
		err = -EBUSY;
		goto out_free_netdev;
	}

	/*
	 * Lacking any better mechanism to allocate a MAC address we use a
	 * random one ...
	 */
	random_ether_addr(netdev->dev_addr);

	err = register_netdev(netdev);
	if (err) {
		printk(KERN_ERR "MIPSNet: failed to register netdev.\n");
		goto out_free_region;
	}

	return 0;

out_free_region:
	release_region(netdev->base_addr, MIPSNET_IO_EXTENT);

out_free_netdev:
	free_netdev(netdev);

out:
	return err;
}

static int __devexit mipsnet_device_remove(struct device *device)
{
	struct net_device *dev = dev_get_drvdata(device);

	unregister_netdev(dev);
	release_region(dev->base_addr, MIPSNET_IO_EXTENT);
	free_netdev(dev);
	dev_set_drvdata(device, NULL);

	return 0;
}

static struct device_driver mipsnet_driver = {
	.name	= mipsnet_string,
	.bus	= &platform_bus_type,
	.probe	= mipsnet_probe,
	.remove	= __devexit_p(mipsnet_device_remove),
};

static void mipsnet_platform_release(struct device *device)
{
	struct platform_device *pldev;

	/* free device */
	pldev = to_platform_device(device);
	kfree(pldev);
}

static int __init mipsnet_init_module(void)
{
	struct platform_device *pldev;
	int err;

	printk(KERN_INFO "MIPSNet Ethernet driver. Version: %s. "
	       "(c)2005 MIPS Technologies, Inc.\n", MIPSNET_VERSION);

	if (driver_register(&mipsnet_driver)) {
		printk(KERN_ERR "Driver registration failed\n");
		err = -ENODEV;
		goto out;
	}

        if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
		err = -ENOMEM;
		goto out_unregister_driver;
	}

	memset (pldev, 0, sizeof (*pldev));
	pldev->name		= mipsnet_string;
	pldev->id		= 0;
	pldev->dev.release	= mipsnet_platform_release;

	if (platform_device_register(pldev)) {
		err = -ENODEV;
		goto out_free_pldev;
	}

        if (!pldev->dev.driver) {
		/*
		 * The driver was not bound to this device, there was
                 * no hardware at this address. Unregister it, as the
		 * release fuction will take care of freeing the
		 * allocated structure
		 */
		platform_device_unregister (pldev);
	}

	mips_plat_dev		= pldev;

	return 0;

out_free_pldev:
	kfree(pldev);

out_unregister_driver:
	driver_unregister(&mipsnet_driver);
out:
	return err;
}

static void __exit mipsnet_exit_module(void)
{
	pr_debug("MIPSNet Ethernet driver exiting\n");

	driver_unregister(&mipsnet_driver);
}

module_init(mipsnet_init_module);
module_exit(mipsnet_exit_module);
