diff --git a/nic/device.c b/nic/device.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..c3b2802baa8299a35fef107992f1bcb884a5a0a7 100644
--- a/nic/device.c
+++ b/nic/device.c
@@ -0,0 +1,145 @@
+/*
+ * Device initialization and cleanup for White-Rabbit switch network interface
+ *
+ * Copyright (C) 2010 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ * Parts are from previous work by Tomasz Wlostowski <tomasz.wlostowsk@cern.ch>
+ * Parts are from previous work by  Emilio G. Cota <cota@braap.org>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include "wr-nic.h"
+
+/* The remove function is used by probe, so it's not __devexit */
+static int __devexit wrn_remove(struct platform_device *pdev)
+{
+	struct wrn_dev *wrn = pdev->dev.platform_data;
+	struct resource *res;
+	int i;
+
+	for (i = 0; i < WRN_NR_ENDPOINTS; i++) {
+		if (wrn->dev[i]) {
+			wrn_endpoint_remove(wrn->dev[i]);
+			free_netdev(wrn->dev[i]);
+			wrn->dev[i] = NULL;
+		}
+	}
+
+	if (wrn->base_nic)	iounmap(wrn->base_nic);
+	if (wrn->base_ppsg)	iounmap(wrn->base_ppsg);
+	if (wrn->base_calib)	iounmap(wrn->base_calib);
+	if (wrn->base_stamp)	iounmap(wrn->base_stamp);
+
+	if (wrn->irq_registered) {
+		res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+		free_irq(res->start, wrn);
+	}
+	return 0;
+}
+
+/* This helper is used by probe below, to avoid code replication */
+static int __devinit __wrn_ioremap(struct platform_device *pdev, int n,
+				    void __iomem **ptr)
+{
+	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, n);
+	if (!res) {
+		dev_err(&pdev->dev, "No resource %i defined\n", n);
+		return -ENOMEM;
+	}
+	*ptr = ioremap(res->start, res->end + 1 - res->start);
+	if (!*ptr) {
+		dev_err(&pdev->dev, "Ioremap for resource %i failed\n", n);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+static int __devinit wrn_probe(struct platform_device *pdev)
+{
+	struct net_device *netdev;
+	struct wrn_devpriv *priv;
+	struct wrn_dev *wrn = pdev->dev.platform_data;
+	struct resource *res;
+	int i, err = 0;
+
+	/* no need to lock_irq: we only protect count and continue unlocked */
+	spin_lock(&wrn->lock);
+	if (++wrn->use_count != 1) {
+		--wrn->use_count;
+		spin_unlock(&wrn->lock);
+		return -EBUSY;
+	}
+	spin_unlock(&wrn->lock);
+
+	/* These memory regions are mapped once for all endpoints */
+	if ( (err = __wrn_ioremap(pdev, WRN_RES_MEM_NIC, &wrn->base_nic)) )
+		goto out;
+	if ( (err = __wrn_ioremap(pdev, WRN_RES_MEM_PPSG, &wrn->base_ppsg)) )
+		goto out;
+	if ( (err = __wrn_ioremap(pdev, WRN_RES_MEM_CALIB, &wrn->base_calib)) )
+		goto out;
+	if ( (err = __wrn_ioremap(pdev, WRN_RES_MEM_STAMP, &wrn->base_stamp)) )
+		goto out;
+
+	/* get the interrupt number from the resource */
+	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+	err = request_irq(res->start, wrn_interrupt,
+			  IRQF_TRIGGER_LOW | IRQF_SHARED,
+			  DRV_NAME,
+			  wrn);
+	if (err) goto out;
+	wrn->irq_registered = 1;
+
+	/* Finally, register one interface per endpoint */
+	memset(wrn->dev, 0, sizeof(wrn->dev));
+	for (i = 0; i < WRN_NR_ENDPOINTS; i++) {
+		netdev = alloc_etherdev(sizeof(struct wrn_devpriv));
+		if (!netdev) {
+			dev_err(&pdev->dev, "Etherdev alloc failed.\n");
+			err = -ENOMEM;
+			goto out;
+		}
+		priv = netdev_priv(netdev);
+		priv->wrn = wrn;
+		priv->ep_number = i;
+
+		/* The netdevice thing is registered from the endpoint */
+		err = wrn_endpoint_probe(netdev);
+		if (err == -ENODEV)
+			break;
+		if (err)
+			goto out;
+		/* This endpoint went in properly */
+		wrn->dev[i] = netdev;
+	}
+	err = 0;
+out:
+	if (err) {
+		/* Call the remove function to avoid duplicating code */
+		wrn_remove(pdev);
+	}
+	return err;
+}
+
+/* This is not static as ./module.c is going to register it */
+struct platform_driver wrn_driver = {
+	.probe		= wrn_probe,
+	.remove		= wrn_remove, /* not __exit_p as probe calls it */
+	/* No suspend or resume by now */
+	.driver		= {
+		.name		= DRV_NAME,
+		.owner		= THIS_MODULE,
+	},
+};
diff --git a/nic/endpoint.c b/nic/endpoint.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..f02fe933acbb02f9d4e6c7ecd41d1f1b17240ccd 100644
--- a/nic/endpoint.c
+++ b/nic/endpoint.c
@@ -0,0 +1,69 @@
+/*
+ * Endoint-specific operations in the White-Rabbit switch network interface
+ *
+ * Copyright (C) 2010 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ * Parts are from previous work by Tomasz Wlostowski <tomasz.wlostowsk@cern.ch>
+ * Parts are from previous work by  Emilio G. Cota <cota@braap.org>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/etherdevice.h>
+#include <linux/io.h>
+
+#include "wr-nic.h"
+
+/* Called for each endpoint, with a valid priv structure in place */
+int wrn_endpoint_probe(struct net_device *netdev)
+{
+	struct wrn_devpriv *priv = netdev_priv(netdev);
+	int err;
+
+	/* FIXME: check if the endpoint does exist or not */
+
+	if (0 /* not existent -- means no more exist after this one */)
+		return -ENODEV;
+
+	/* Errors different from -ENODEV are fatal to insmod */
+	priv->base = ioremap(FPGA_BASE_EP(priv->ep_number), WRN_EP_MEM_SIZE);
+	if (!priv->base) {
+		printk(KERN_ERR DRV_NAME ": ioremap failed for EP %i\n",
+		       priv->ep_number);
+		return -ENOMEM;
+	}
+
+	/* build the device name (FIXME: up or downlink?) */
+	dev_alloc_name(netdev, "wru%d");
+	wrn_netops_init(netdev); /* function in ./nic-core.c */
+	wrn_ethtool_init(netdev); /* function in ./ethtool.c */
+	/* Napi is not supported on this device */
+
+	/* FIXME: mii -- copy from minic */
+
+	/* randomize a MAC address, so lazy users can avoid ifconfig */
+	random_ether_addr(netdev->dev_addr);
+
+	err = register_netdev(netdev);
+	if (err) {
+		printk(KERN_ERR DRV_NAME "Can't register dev %s\n",
+		       netdev->name);
+		iounmap(priv->base);
+		/* ENODEV means "no more" for the caller */
+		return err == -ENODEV ? -EIO : err;
+	}
+	return 0;
+}
+
+/* Called for each endpoint, with a valid priv structure. The caller frees */
+void wrn_endpoint_remove(struct net_device *netdev)
+{
+	struct wrn_devpriv *priv = netdev_priv(netdev);
+
+	unregister_netdev(netdev);
+	iounmap(priv->base);
+}
diff --git a/nic/ethtool.c b/nic/ethtool.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..e3f6000c4b1160f0fbea54923616cb90bd6bcc6a 100644
--- a/nic/ethtool.c
+++ b/nic/ethtool.c
@@ -0,0 +1,99 @@
+/*
+ * Ethtool operations for White-Rabbit switch network interface
+ *
+ * Copyright (C) 2010 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ * Parts are from previous work by Tomasz Wlostowski <tomasz.wlostowsk@cern.ch>
+ * Parts are from previous work by  Emilio G. Cota <cota@braap.org>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/netdevice.h>
+#include <linux/mii.h>
+#include <linux/ethtool.h>
+#include <linux/spinlock.h>
+
+#include "wr-nic.h"
+
+static int wrn_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct wrn_dev *wrn = netdev_priv(dev);
+	int ret;
+
+	spin_lock_irq(&wrn->lock);
+	ret = mii_ethtool_gset(&wrn->mii, cmd);
+	spin_unlock_irq(&wrn->lock);
+
+	cmd->supported=
+		SUPPORTED_FIBRE | /* FIXME: copper sfp? */
+		SUPPORTED_Autoneg |
+		SUPPORTED_1000baseKX_Full;
+	cmd->advertising =
+		ADVERTISED_1000baseKX_Full |
+		ADVERTISED_Autoneg;
+	cmd->port = PORT_FIBRE;
+	cmd->speed = SPEED_1000;
+	cmd->duplex = DUPLEX_FULL;
+	cmd->autoneg = AUTONEG_ENABLE;
+	return ret;
+}
+
+static int wrn_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+	struct wrn_dev *wrn = netdev_priv(dev);
+	int ret;
+
+	spin_lock_irq(&wrn->lock);
+	ret = mii_ethtool_sset(&wrn->mii, cmd);
+	spin_unlock_irq(&wrn->lock);
+
+	return ret;
+}
+
+static int wrn_nwayreset(struct net_device *dev)
+{
+	struct wrn_dev *wrn = netdev_priv(dev);
+	int ret;
+
+	spin_lock_irq(&wrn->lock);
+	ret = mii_nway_restart(&wrn->mii);
+	spin_unlock_irq(&wrn->lock);
+
+	return ret;
+}
+
+static void wrn_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));
+}
+
+/*
+ * These are the operations we support. No coalescing is there since
+ * most of the traffic will just happen within the FPGA switching core.
+ * Similarly, other funcionality like ringparam are not used.
+ * get_eeprom/set_eeprom may be useful for a simple MAC address management.
+ */
+static const struct ethtool_ops wrn_ethtool_ops = {
+	.get_settings	= wrn_get_settings,
+	.set_settings	= wrn_set_settings,
+	.get_drvinfo	= wrn_get_drvinfo,
+	.nway_reset	= wrn_nwayreset,
+	/* Some of the default methods apply for us */
+	.get_link	= ethtool_op_get_link,
+	/* FIXME: get_regs_len and get_regs may be useful for debugging */
+};
+
+int wrn_ethtool_init(struct net_device *netdev)
+{
+	netdev->ethtool_ops = &wrn_ethtool_ops;
+	return 0;
+}
diff --git a/nic/module.c b/nic/module.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0555ac4c4428b02e2f2a579caded3ffa2d16a9de 100644
--- a/nic/module.c
+++ b/nic/module.c
@@ -0,0 +1,79 @@
+/*
+ * Module-related material for wr-nic: load and unload
+ *
+ * Copyright (C) 2010 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ * Parts are from previous work by Tomasz Wlostowski <tomasz.wlostowsk@cern.ch>
+ * Parts are from previous work by  Emilio G. Cota <cota@braap.org>
+ *
+ * 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.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/platform_device.h>
+
+#include "wr-nic.h"
+
+/* Our platform data is actually the device itself, and we have 1 only */
+static struct wrn_dev wrn_dev;
+
+/* The WRN_RES_ names are defined in the header file. Each is 64kB */
+#define __RES(x) .start = x, .end = x + 0x10000 - 1, .flags = IORESOURCE_MEM
+
+static struct resource wrn_resources[] = {
+	[WRN_RES_MEM_NIC]	= { __RES( FPGA_BASE_NIC ) },
+	[WRN_RES_MEM_PPSG]	= { __RES( FPGA_BASE_PPSG ) },
+	[WRN_RES_MEM_CALIB]	= { __RES( FPGA_BASE_CALIB ) },
+	[WRN_RES_MEM_STAMP]	= { __RES( FPGA_BASE_STAMP ) },
+
+	/* Last is the interrupt */
+	[WRN_RES_IRQ] = {
+		.start =	WRN_INTERRUPT,
+		.end =		WRN_INTERRUPT,
+		.flags =	IORESOURCE_IRQ,
+	}
+};
+#undef __RES
+
+static struct platform_device wrn_device = {
+	.name = DRV_NAME,
+	.id = 0,
+	.resource = wrn_resources,
+	.num_resources = ARRAY_SIZE(wrn_resources),
+	.dev = {
+		.platform_data = &wrn_dev,
+		/* dma_mask not used, as we make no DMA */
+	},
+};
+
+/*
+ * Module init and exit stuff. Here we register the platform data
+ * as well, but the driver itself is in device.c
+ */
+int __init wrn_init(void)
+{
+	/* A few fields must be initialized at run time */
+	spin_lock_init(&wrn_dev.lock);
+
+	platform_device_register(&wrn_device);
+	platform_driver_register(&wrn_driver);
+	return -EAGAIN;
+}
+
+void __exit wrn_exit(void)
+{
+	platform_driver_unregister(&wrn_driver);
+	platform_device_unregister(&wrn_device);
+	return;
+}
+
+module_init(wrn_init);
+module_exit(wrn_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:wr-nic");
diff --git a/nic/nic-core.c b/nic/nic-core.c
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8ed67cfa15c90a08098b2f0a67fc361363fed260 100644
--- a/nic/nic-core.c
+++ b/nic/nic-core.c
@@ -0,0 +1,131 @@
+/*
+ * Core file for White-Rabbit switch network interface
+ *
+ * Copyright (C) 2010 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ * Parts are from previous work by Tomasz Wlostowski <tomasz.wlostowsk@cern.ch>
+ * Parts are from previous work by  Emilio G. Cota <cota@braap.org>
+ *
+ * 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.
+ */
+
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/errno.h>
+#include <linux/spinlock.h>
+
+#include "wr-nic.h"
+
+/* These are the standard netword device operations */
+static int wrn_open(struct net_device *netdev)
+{
+	struct wrn_devpriv *priv = netdev_priv(netdev);
+	struct wrn_dev *wrn = priv->wrn;
+
+	netdev_dbg(netdev, "%s\n", __func__);
+
+	if (!is_valid_ether_addr(netdev->dev_addr))
+		return -EADDRNOTAVAIL;
+
+#if 0 /* FIXME: the whole open method is missing */
+	minic_writel(nic, MINIC_REG_MCR, 0);
+	minic_disable_irq(nic, 0xffffffff);
+	ep_enable(netdev);
+
+	netif_carrier_off(netdev);
+
+	init_timer(&nic->link_timer);
+	nic->link_timer.data = (unsigned long)netdev;
+	nic->link_timer.function = minic_check_link;
+	mod_timer(&nic->link_timer, jiffies + LINK_POLL_INTERVAL);
+
+	nic->synced = false;
+	nic->syncing_counters = false;
+
+	nic->rx_base = MINIC_PBUF_SIZE >> 1;
+	nic->rx_size = MINIC_PBUF_SIZE >> 1;
+
+	nic->tx_base = 0;
+	nic->tx_size = MINIC_PBUF_SIZE >> 1;
+
+	nic->tx_hwtstamp_enable = 0;
+	nic->rx_hwtstamp_enable = 0;
+	nic->tx_hwtstamp_oob = 1;
+
+	minic_new_rx_buffer(nic);
+
+	minic_enable_irq(nic, MINIC_EIC_IER_RX); // enable RX irq
+	minic_writel(nic, MINIC_REG_MCR, MINIC_MCR_RX_EN); // enable RX
+
+	if (netif_queue_stopped(nic->netdev)) {
+		netif_wake_queue(netdev);
+	} else {
+		netif_start_queue(netdev);
+	}
+
+	nic->iface_up = 0;
+#endif
+	return 0;
+}
+
+static int wrn_close(struct net_device *netdev)
+{
+	/* FIXME: the close method is missing */
+	return 0;
+}
+
+static int wrn_set_mac_address(struct net_device *netdev, void* addr)
+{
+	/* FIXME: set_mac_address is missing */
+	return 0;
+}
+
+static int wrn_start_xmit(struct sk_buff *skb, struct net_device *netdev)
+{
+	/* FIXME: start_xmit is missing */
+	return -ENODEV;
+}
+
+struct net_device_stats *wrn_get_stats(struct net_device *netdev)
+{
+	/* FIXME: getstats is missing */
+	return NULL;
+}
+
+static int wrn_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
+{
+	/* FIXME: ioctl is missing */
+	return -ENOIOCTLCMD;
+}
+
+static const struct net_device_ops wrn_netdev_ops = {
+	.ndo_open		= wrn_open,
+	.ndo_stop		= wrn_close,
+	.ndo_start_xmit		= wrn_start_xmit,
+	.ndo_validate_addr	= eth_validate_addr,
+	.ndo_get_stats		= wrn_get_stats,
+	.ndo_set_mac_address	= wrn_set_mac_address,
+	.ndo_do_ioctl		= wrn_ioctl,
+#if 0
+	/* Missing ops, possibly to add later (FIXME?) */
+	.ndo_set_multicast_list	= wrn_set_multicast_list,
+	.ndo_change_mtu		= wrn_change_mtu,
+	/* There are several more, but not really useful for us */
+#endif
+};
+
+
+int wrn_netops_init(struct net_device *netdev)
+{
+	netdev->netdev_ops = &wrn_netdev_ops;
+	return 0;
+}
+
+irqreturn_t wrn_interrupt(int irq, void *dev_id)
+{
+	/* FIXME */
+	return IRQ_HANDLED;
+}
diff --git a/nic/nic-hardware.h b/nic/nic-hardware.h
new file mode 100644
index 0000000000000000000000000000000000000000..4fcfa9956178eac643c417e83a2fb9a7268ddf47
--- /dev/null
+++ b/nic/nic-hardware.h
@@ -0,0 +1,48 @@
+#ifndef __WR_NIC_HARDWARE_H__
+#define __WR_NIC_HARDWARE_H__
+
+/* Our host CPU is this one, no way out of it */
+#include <mach/at91sam9263.h>
+
+#include "wr_nic.wb.h" /* wbgen2 file, with local fixes (64KB of area) */
+
+/* FIXME: This one is wrong, should stack on wr_vic.c instead */
+#define WRN_INTERRUPT		AT91SAM9263_ID_IRQ0
+
+/* Physical memory addresses. Should we import from other places? */
+
+/* FIXME: Where is the wr_nic 64kB area in all this? */
+
+/* The following is fake, just to make stuff compile - FIXME FIXME FIXME */
+#define FPGA_BASE_NIC           _FPGA_BUS_2_ADDR(4)
+#define FPGA_BASE_PPSG          _FPGA_BUS_2_ADDR(5)
+#define FPGA_BASE_CALIB         _FPGA_BUS_2_ADDR(6)
+#define FPGA_BASE_STAMP         _FPGA_BUS_2_ADDR(7)
+#define FPGA_BASE_EP(x)         _FPGA_BUS_2_ADDR(8+(x))
+
+
+/* Following defines come straight from board-whiterabbit-mch.c */
+#define _FPGA_BUS_2_ADDR(bus) (0x70000000 + (bus) * 0x10000)
+
+#define FPGA_BASE_REVID     _FPGA_BUS_2_ADDR(0)
+#define FPGA_BASE_GPIO      _FPGA_BUS_2_ADDR(1)
+#define FPGA_BASE_SPIM      _FPGA_BUS_2_ADDR(2)
+#define FPGA_BASE_VIC       _FPGA_BUS_2_ADDR(3)
+#define FPGA_BASE_MINIC_UP1 _FPGA_BUS_2_ADDR(4)
+#define FPGA_BASE_MINIC_UP0 _FPGA_BUS_2_ADDR(5)
+#define FPGA_BASE_MINIC_DP0 _FPGA_BUS_2_ADDR(6)
+#define FPGA_BASE_MINIC_DP1 _FPGA_BUS_2_ADDR(7)
+#define FPGA_BASE_MINIC_DP2 _FPGA_BUS_2_ADDR(8)
+#define FPGA_BASE_MINIC_DP3 _FPGA_BUS_2_ADDR(9)
+#define FPGA_BASE_MINIC_DP4 _FPGA_BUS_2_ADDR(10)
+#define FPGA_BASE_MINIC_DP5 _FPGA_BUS_2_ADDR(11)
+#define FPGA_BASE_MINIC_DP6 _FPGA_BUS_2_ADDR(12)
+#define FPGA_BASE_MINIC_DP7    _FPGA_BUS_2_ADDR(13)
+#define FPGA_BASE_PPS_GEN      _FPGA_BUS_2_ADDR(14)
+#define FPGA_BASE_CALIBRATOR   _FPGA_BUS_2_ADDR(15)
+#define FPGA_BASE_RTU          _FPGA_BUS_2_ADDR(16)
+#define FPGA_BASE_RTU_TESTUNIT _FPGA_BUS_2_ADDR(17)
+
+#define WR_MINIC_SIZE     0x10000
+
+#endif /* __WR_NIC_HARDWARE_H__ */
diff --git a/nic/wr-nic.h b/nic/wr-nic.h
new file mode 100644
index 0000000000000000000000000000000000000000..2a34945143bf1ac7f88f3365677ad719833a08ce
--- /dev/null
+++ b/nic/wr-nic.h
@@ -0,0 +1,109 @@
+/*
+ * wr-nic definitions, structures and prototypes
+ *
+ * Copyright (C) 2010 CERN (www.cern.ch)
+ * Author: Alessandro Rubini <rubini@gnudd.com>
+ * Parts are from previous work by Tomasz Wlostowski <tomasz.wlostowsk@cern.ch>
+ * Parts are from previous work by  Emilio G. Cota <cota@braap.org>
+ *
+ * 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.
+ */
+#ifndef __WR_NIC_H__
+#define __WR_NIC_H__
+#include <linux/mii.h>
+#include <linux/irqreturn.h>
+#include <linux/spinlock.h>
+
+#include "nic-hardware.h" /* Magic numbers: please fix them as needed */
+
+#define DRV_NAME "wr-nic" /* Used in messages and device/driver names */
+#define DRV_VERSION "0.1" /* For ethtool->get_drvinfo -- FIXME: auto-vers */
+
+/* Structures we are using but may remain opaque */
+struct net_device;
+
+/*
+ * This is the main data structure for our NIC device
+ */
+#define WRN_NR_ENDPOINTS 24
+
+struct wrn_dev {
+	/* Base addresses for the various areas */
+	void __iomem *base_nic; /* nic includes packet RAM */
+	void __iomem *base_ppsg;
+	void __iomem *base_calib;
+	void __iomem *base_stamp;
+	/* The base for each endpoint is ioremapped by the EP itself */
+
+	spinlock_t lock;
+
+	struct net_device *dev[WRN_NR_ENDPOINTS];
+
+	/* FIXME: all dev fields must be verified */
+	//int tx_hwtstamp_enable;
+	//int rx_hwtstamp_enable;
+
+	//int tx_hwtstamp_oob;
+
+	//struct platform_device	*pdev;
+	//struct device		*dev;
+	//struct net_device	*netdev;
+
+	//struct net_device_stats	stats;
+	//struct napi_struct	napi;
+	//struct sk_buff		*current_skb;
+	//struct timer_list	link_timer;
+
+	//unsigned int rx_head, rx_avail, rx_base, rx_size;
+	//unsigned int tx_head, tx_avail, tx_base, tx_size;
+
+	//bool synced;
+	//bool syncing_counters;
+	//int iface_up;
+
+	//u32 cur_rx_desc;
+
+	struct mii_if_info mii; /* for ethtool operations */
+
+	int use_count; /* only used at probe time */
+	int irq_registered;
+};
+
+/* Each network device has one such priv structure */
+struct wrn_devpriv {
+	struct wrn_dev *wrn;
+	void __iomem *base; /* each EP has its own memory area */
+	int ep_number;
+	int flags; /* uplink/downlink and possibly more */
+	/* FIXME: other fields needed for endpoint-specific struct? */
+};
+#define WRN_EP_MEM_SIZE 0x10000 /* 64k like other areas */
+
+/* Our resources. The names are used as indexes in the resource array */
+enum wrn_resnames {
+	WRN_RES_MEM_NIC = 0,
+	WRN_RES_MEM_PPSG,
+	WRN_RES_MEM_CALIB,
+	WRN_RES_MEM_STAMP,
+	/* Irq is last, so platform_get_resource() can use previous enums */
+	WRN_RES_IRQ,
+};
+
+/* Following functions in in nic-core.c */
+extern irqreturn_t wrn_interrupt(int irq, void *dev_id);
+extern int wrn_netops_init(struct net_device *netdev);
+
+/* Following data in device.c */
+struct platform_driver;
+extern struct platform_driver wrn_driver;
+
+/* Following functions in ethtool.c */
+extern int wrn_ethtool_init(struct net_device *netdev);
+
+/* Following functions in endpoint.c */
+extern int  wrn_endpoint_probe(struct net_device *netdev);
+extern void wrn_endpoint_remove(struct net_device *netdev);
+
+#endif /* __WR_NIC_H__ */