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__ */