--- a/NEWS Fri Feb 16 13:30:46 2007 +0000
+++ b/NEWS Fri Feb 16 17:13:39 2007 +0000
@@ -4,6 +4,24 @@
-------------------------------------------------------------------------------
+Changes in version 1.3.0:
+
+* Added Intel e100 ethernet driver.
+* Removed "ec_eoeif_count" master module parameter.
+* Introduced "device IDs" to tell a master to wait for certain ethernet
+ devices.
+* Added "main" and "backup" parameters to master module. To hand over
+ device ID lists.
+* Changed format of sysconfig file and accordingly adjusted functionality
+ of the init script to handle device IDs.
+* Device interface changes:
+ - Replaced ecdev_register() and ecdev_unregister() with ecdev_offer() and
+ ecdev_withdraw(), respectively. The device modules now offer all their
+ devices to the master, which decides, which ones to register.
+* Removed EtherCAT line comments from 8139too drivers.
+
+-------------------------------------------------------------------------------
+
Changes in version 1.2.0:
* Serveral fixes of bugs and stability issues. Master should now run fine
--- a/devices/8139too-2.6.13-ethercat.c Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/8139too-2.6.13-ethercat.c Fri Feb 16 17:13:39 2007 +0000
@@ -153,8 +153,6 @@
#include <asm/uaccess.h>
#include <asm/irq.h>
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#include "../globals.h"
#include "ecdev.h"
@@ -162,8 +160,6 @@
" EtherCAT-capable Fast Ethernet driver " \
DRV_VERSION ", master " EC_MASTER_VERSION
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
#define PFX DRV_NAME ": "
/* Default Message level */
@@ -215,15 +211,6 @@
/* bitmapped message enable number */
static int debug = -1;
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-static int ec_device_index = -1;
-static int ec_device_master_index = 0;
-static ec_device_t *rtl_ec_dev;
-struct net_device *rtl_ec_net_dev = NULL;
-
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/*
* Receive ring size
* Warning: 64K ring has hardware issues and may lock up.
@@ -338,13 +325,9 @@
{0,}
};
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
/* prevent driver from being loaded automatically */
//MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
static struct {
const char str[ETH_GSTRING_LEN];
} ethtool_stats_keys[] = {
@@ -664,17 +647,15 @@
struct mii_if_info mii;
unsigned int regs_len;
unsigned long fifo_copy_timeout;
+
+ ec_device_t *ecdev;
};
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(EC_MASTER_VERSION);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
@@ -684,19 +665,8 @@
MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-module_param(ec_device_index, int, -1);
-module_param(ec_device_master_index, int, 0);
-MODULE_PARM_DESC(ec_device_index,
- "Index of the device reserved for EtherCAT.");
-MODULE_PARM_DESC(ec_device_master_index,
- "Index of the EtherCAT master to register the device.");
-
void ec_poll(struct net_device *);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
static int rtl8139_open (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location);
@@ -1046,15 +1016,6 @@
assert (dev != NULL);
tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (board_idx == ec_device_index) {
- rtl_ec_net_dev = dev;
- strcpy(dev->name, "ec0");
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
ioaddr = tp->mmio_addr;
assert (ioaddr != NULL);
@@ -1106,17 +1067,20 @@
tp->mii.reg_num_mask = 0x1f;
/* dev is fully set up and ready to use now */
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+
+ // offer device to EtherCAT master module
+ if (ecdev_offer(dev, &tp->ecdev, "8139too", board_idx,
+ ec_poll, THIS_MODULE)) {
+ printk(KERN_ERR PFX "Failed to offer device.\n");
+ goto err_out;
+ }
+
+ if (!tp->ecdev) {
DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
i = register_netdev (dev);
if (i) goto err_out;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
pci_set_drvdata (pdev, dev);
printk (KERN_INFO "%s: %s at 0x%lx, "
@@ -1189,6 +1153,11 @@
if (rtl_chip_info[tp->chipset].flags & HasHltClk)
RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */
+ if (tp->ecdev && ecdev_open(tp->ecdev)) {
+ ecdev_withdraw(tp->ecdev);
+ goto err_out;
+ }
+
return 0;
err_out:
@@ -1201,17 +1170,18 @@
static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
assert (dev != NULL);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ ecdev_close(tp->ecdev);
+ ecdev_withdraw(tp->ecdev);
+ }
+ else {
unregister_netdev (dev);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
__rtl8139_cleanup_dev (dev);
pci_disable_device (pdev);
}
@@ -1412,30 +1382,19 @@
int retval;
void __iomem *ioaddr = tp->mmio_addr;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
retval = request_irq(dev->irq, rtl8139_interrupt,
SA_SHIRQ, dev->name, dev);
if (retval)
return retval;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
&tp->tx_bufs_dma);
tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
&tp->rx_ring_dma);
if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- free_irq(dev->irq, dev);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
+ if (!tp->ecdev) free_irq(dev->irq, dev);
if (tp->tx_bufs)
pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
tp->tx_bufs, tp->tx_bufs_dma);
@@ -1453,9 +1412,7 @@
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
netif_start_queue (dev);
if (netif_msg_ifup(tp))
@@ -1468,8 +1425,6 @@
rtl8139_start_thread(dev);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return 0;
}
@@ -1478,19 +1433,16 @@
{
struct rtl8139_private *tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ void __iomem *ioaddr = tp->mmio_addr;
+ uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
+ ecdev_link_state(tp->ecdev, state ? 1 : 0);
+ }
+ else {
if (tp->phys[0] >= 0) {
mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
}
- } else {
- void __iomem *ioaddr = tp->mmio_addr;
- uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
- ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
}
/* Start the hardware at open or resume. */
@@ -1555,14 +1507,9 @@
if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev)
/* Enable all known interrupts by setting the interrupt mask. */
RTL_W16 (IntrMask, rtl8139_intr_mask);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
@@ -1821,30 +1768,27 @@
if (tmp8 & CmdTxEnb)
RTL_W8 (ChipCmd, CmdRxEnb);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- spin_lock(&tp->rx_lock);
- /* Disable interrupts by clearing the interrupt mask. */
- RTL_W16 (IntrMask, 0x0000);
-
- /* Stop a shared interrupt from scavenging while we are. */
- spin_lock_irqsave (&tp->lock, flags);
- rtl8139_tx_clear (tp);
- spin_unlock_irqrestore (&tp->lock, flags);
-
- /* ...and finally, reset everything */
- if (netif_running(dev)) {
- rtl8139_hw_start (dev);
- netif_wake_queue (dev);
- }
- spin_unlock(&tp->rx_lock);
- } else {
- rtl8139_tx_clear (tp);
- rtl8139_hw_start (dev);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (tp->ecdev) {
+ rtl8139_tx_clear (tp);
+ rtl8139_hw_start (dev);
+ }
+ else {
+ spin_lock(&tp->rx_lock);
+ /* Disable interrupts by clearing the interrupt mask. */
+ RTL_W16 (IntrMask, 0x0000);
+
+ /* Stop a shared interrupt from scavenging while we are. */
+ spin_lock_irqsave (&tp->lock, flags);
+ rtl8139_tx_clear (tp);
+ spin_unlock_irqrestore (&tp->lock, flags);
+
+ /* ...and finally, reset everything */
+ if (netif_running(dev)) {
+ rtl8139_hw_start (dev);
+ netif_wake_queue (dev);
+ }
+ spin_unlock(&tp->rx_lock);
+ }
}
@@ -1858,30 +1802,19 @@
/* Calculate the next Tx descriptor entry. */
entry = tp->cur_tx % NUM_TX_DESC;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
/* Note: the chip doesn't have auto-pad! */
if (likely(len < TX_BUF_SIZE)) {
if (len < ETH_ZLEN)
memset(tp->tx_buf[entry], 0, ETH_ZLEN);
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
- if (dev != rtl_ec_net_dev) {
- dev_kfree_skb(skb);
- }
+ if (!tp->ecdev) dev_kfree_skb(skb);
} else {
- if (dev != rtl_ec_net_dev) {
- dev_kfree_skb(skb);
- }
+ if (!tp->ecdev) dev_kfree_skb(skb);
tp->stats.tx_dropped++;
return 0;
}
- if (dev != rtl_ec_net_dev) {
- spin_lock_irq(&tp->lock);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
+ if (!tp->ecdev) spin_lock_irq(&tp->lock);
RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
@@ -1890,9 +1823,7 @@
tp->cur_tx++;
wmb();
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
netif_stop_queue (dev);
spin_unlock_irq(&tp->lock);
@@ -1902,8 +1833,6 @@
dev->name, len, entry);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return 0;
}
@@ -1961,10 +1890,8 @@
tx_left--;
}
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#ifndef RTL8139_NDEBUG
- if (dev != rtl_ec_net_dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+ if (!tp->ecdev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
dev->name, dirty_tx, tp->cur_tx);
dirty_tx += NUM_TX_DESC;
@@ -1975,13 +1902,8 @@
if (tp->dirty_tx != dirty_tx) {
tp->dirty_tx = dirty_tx;
mb();
-
- if (dev != rtl_ec_net_dev) {
- netif_wake_queue (dev);
- }
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) netif_wake_queue (dev);
+ }
}
@@ -2114,15 +2036,9 @@
RTL_R16 (RxBufAddr),
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- while ((dev == rtl_ec_net_dev || netif_running(dev))
+ while ((tp->ecdev || netif_running(dev))
&& received < budget
&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
u32 ring_offset = cur_rx % RX_BUF_LEN;
u32 rx_status;
unsigned int pkt_size;
@@ -2135,17 +2051,12 @@
rx_size = rx_status >> 16;
pkt_size = rx_size - 4;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
if (netif_msg_rx_status(tp))
printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x,"
" cur %4.4x.\n", dev->name, rx_status,
rx_size, cur_rx);
}
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
#if RTL8139_DEBUG > 2
{
int i;
@@ -2193,9 +2104,14 @@
goto out;
}
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ ecdev_receive(tp->ecdev,
+ &rx_ring[ring_offset + 4], pkt_size);
+ dev->last_rx = jiffies;
+ tp->stats.rx_bytes += pkt_size;
+ tp->stats.rx_packets++;
+ }
+ else {
/* Malloc up new buffer, compatible with net-2e. */
/* Omit the four octet CRC from the length. */
@@ -2220,20 +2136,11 @@
} else {
if (net_ratelimit())
printk(KERN_WARNING
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
+ "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
tp->stats.rx_dropped++;
}
- } else {
- ecdev_receive(rtl_ec_dev,
- &rx_ring[ring_offset + 4], pkt_size);
- dev->last_rx = jiffies;
- tp->stats.rx_bytes += pkt_size;
- tp->stats.rx_packets++;
}
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
received++;
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -2339,19 +2246,15 @@
return !done;
}
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
void ec_poll(struct net_device *dev)
{
rtl8139_interrupt(0, dev, NULL);
}
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
-irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
- struct pt_regs *regs)
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
+ struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_instance;
struct rtl8139_private *tp = netdev_priv(dev);
@@ -2360,20 +2263,17 @@
int link_changed = 0; /* avoid bogus "uninit" warning */
int handled = 0;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ status = RTL_R16 (IntrStatus);
+ }
+ else {
spin_lock (&tp->lock);
status = RTL_R16 (IntrStatus);
/* shared irq? */
if (unlikely((status & rtl8139_intr_mask) == 0))
goto out;
- } else {
- status = RTL_R16 (IntrStatus);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
handled = 1;
@@ -2381,9 +2281,7 @@
if (unlikely(status == 0xFFFF))
goto out;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
/* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) {
RTL_W16 (IntrMask, 0);
@@ -2391,8 +2289,6 @@
}
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* Acknowledge all of the current interrupt sources ASAP, but
an first get an additional status bit from CSCR. */
if (unlikely(status & RxUnderrun))
@@ -2404,24 +2300,20 @@
/* Receive packets are processed by poll routine.
If not running start it now. */
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
if (status & RxAckBits){
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ /* EtherCAT device: Just receive all frames */
+ rtl8139_rx(dev, tp, 100); // FIXME
+ }
+ else {
/* Mark for polling */
if (netif_rx_schedule_prep(dev)) {
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
__netif_rx_schedule (dev);
}
- } else {
- /* EtherCAT device: Just receive all frames */
- rtl8139_rx(dev, tp, 100); // FIXME
}
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* Check uncommon events with one test. */
if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
rtl8139_weird_interrupt (dev, tp, ioaddr,
@@ -2433,14 +2325,7 @@
RTL_W16 (IntrStatus, TxErr);
}
out:
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- spin_unlock (&tp->lock);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) spin_unlock (&tp->lock);
DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
dev->name, RTL_R16 (IntrStatus));
@@ -2467,9 +2352,17 @@
int ret = 0;
unsigned long flags;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ /* Stop the chip's Tx and Rx DMA processes. */
+ RTL_W8 (ChipCmd, 0);
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ RTL_W16 (IntrMask, 0);
+
+ /* Update the error counts. */
+ tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ RTL_W32 (RxMissed, 0);
+ } else {
netif_stop_queue (dev);
if (tp->thr_pid >= 0) {
@@ -2503,19 +2396,7 @@
synchronize_irq (dev->irq); /* racy, but that's ok here */
free_irq (dev->irq, dev);
- } else {
- /* Stop the chip's Tx and Rx DMA processes. */
- RTL_W8 (ChipCmd, 0);
-
- /* Disable interrupts by clearing the interrupt mask. */
- RTL_W16 (IntrMask, 0);
-
- /* Update the error counts. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
- RTL_W32 (RxMissed, 0);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
rtl8139_tx_clear (tp);
@@ -2730,13 +2611,9 @@
struct rtl8139_private *np = netdev_priv(dev);
int rc;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running(dev))
+ if (np->ecdev || !netif_running(dev))
return -EINVAL;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
spin_unlock_irq(&np->lock);
@@ -2751,17 +2628,13 @@
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || netif_running(dev)) {
+ if (tp->ecdev || netif_running(dev)) {
spin_lock_irqsave (&tp->lock, flags);
tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return &tp->stats;
}
@@ -2837,13 +2710,9 @@
pci_save_state (pdev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running (dev))
+ if (tp->ecdev || !netif_running (dev))
return 0;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
netif_device_detach (dev);
spin_lock_irqsave (&tp->lock, flags);
@@ -2867,16 +2736,11 @@
static int rtl8139_resume (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
pci_restore_state (pdev);
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running (dev))
+ if (tp->ecdev || !netif_running (dev))
return 0;
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
pci_set_power_state (pdev, PCI_D0);
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
@@ -2901,69 +2765,20 @@
static int __init rtl8139_init_module (void)
{
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- printk(KERN_INFO RTL8139_DRIVER_NAME "\n");
- printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
-
- if (pci_module_init(&rtl8139_pci_driver) < 0) {
- printk(KERN_ERR "Failed to init PCI module.\n");
- goto out_return;
- }
-
- if (rtl_ec_net_dev) {
- printk(KERN_INFO "Registering EtherCAT device...\n");
- if (!(rtl_ec_dev = ecdev_register(ec_device_master_index,
- rtl_ec_net_dev, ec_poll, THIS_MODULE))) {
- printk(KERN_ERR "Failed to register EtherCAT device!\n");
- goto out_pci;
- }
-
- printk(KERN_INFO "Opening EtherCAT device...\n");
- if (ecdev_open(rtl_ec_dev)) {
- printk(KERN_ERR "Failed to open EtherCAT device!\n");
- goto out_unregister;
- }
-
- printk(KERN_INFO "EtherCAT device ready.\n");
- } else {
- printk(KERN_WARNING "No EtherCAT device registered!\n");
- }
-
- return 0;
-
- out_unregister:
- printk(KERN_INFO "Unregistering EtherCAT device...\n");
- ecdev_unregister(ec_device_master_index, rtl_ec_dev);
- rtl_ec_dev = NULL;
- out_pci:
- pci_unregister_driver(&rtl8139_pci_driver);
- out_return:
- return -1;
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ /* when we're a module, we always print a version message,
+ * even if no 8139 board is found.
+ */
+#ifdef MODULE
+ printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
+ return pci_module_init (&rtl8139_pci_driver);
}
static void __exit rtl8139_cleanup_module (void)
{
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
-
- if (rtl_ec_net_dev) {
- printk(KERN_INFO "Closing EtherCAT device...\n");
- ecdev_close(rtl_ec_dev);
- printk(KERN_INFO "Unregistering EtherCAT device...\n");
- ecdev_unregister(ec_device_master_index, rtl_ec_dev);
- rtl_ec_dev = NULL;
- }
-
- pci_unregister_driver(&rtl8139_pci_driver);
-
- printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ pci_unregister_driver (&rtl8139_pci_driver);
}
--- a/devices/8139too-2.6.17-ethercat.c Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/8139too-2.6.17-ethercat.c Fri Feb 16 17:13:39 2007 +0000
@@ -153,8 +153,6 @@
#include <asm/uaccess.h>
#include <asm/irq.h>
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#include "../globals.h"
#include "ecdev.h"
@@ -162,8 +160,6 @@
" EtherCAT-capable Fast Ethernet driver " \
DRV_VERSION ", master " EC_MASTER_VERSION
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
#define PFX DRV_NAME ": "
/* Default Message level */
@@ -215,15 +211,6 @@
/* bitmapped message enable number */
static int debug = -1;
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-static int ec_device_index = -1;
-static int ec_device_master_index = 0;
-static ec_device_t *rtl_ec_dev;
-struct net_device *rtl_ec_net_dev = NULL;
-
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/*
* Receive ring size
* Warning: 64K ring has hardware issues and may lock up.
@@ -338,13 +325,9 @@
{0,}
};
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
/* prevent driver from being loaded automatically */
//MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
static struct {
const char str[ETH_GSTRING_LEN];
} ethtool_stats_keys[] = {
@@ -666,17 +649,15 @@
struct mii_if_info mii;
unsigned int regs_len;
unsigned long fifo_copy_timeout;
+
+ ec_device_t *ecdev;
};
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(EC_MASTER_VERSION);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
@@ -686,19 +667,8 @@
MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-module_param(ec_device_index, int, -1);
-module_param(ec_device_master_index, int, 0);
-MODULE_PARM_DESC(ec_device_index,
- "Index of the device reserved for EtherCAT.");
-MODULE_PARM_DESC(ec_device_master_index,
- "Index of the EtherCAT master to register the device.");
-
void ec_poll(struct net_device *);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
static int rtl8139_open (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location);
@@ -1050,15 +1020,6 @@
assert (dev != NULL);
tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (board_idx == ec_device_index) {
- rtl_ec_net_dev = dev;
- strcpy(dev->name, "ec0");
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
ioaddr = tp->mmio_addr;
assert (ioaddr != NULL);
@@ -1110,17 +1071,20 @@
tp->mii.reg_num_mask = 0x1f;
/* dev is fully set up and ready to use now */
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+
+ // offer device to EtherCAT master module
+ if (ecdev_offer(dev, &tp->ecdev, "8139too", board_idx,
+ ec_poll, THIS_MODULE)) {
+ printk(KERN_ERR PFX "Failed to offer device.\n");
+ goto err_out;
+ }
+
+ if (!tp->ecdev) {
DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
i = register_netdev (dev);
if (i) goto err_out;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
pci_set_drvdata (pdev, dev);
printk (KERN_INFO "%s: %s at 0x%lx, "
@@ -1193,6 +1157,11 @@
if (rtl_chip_info[tp->chipset].flags & HasHltClk)
RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */
+ if (tp->ecdev && ecdev_open(tp->ecdev)) {
+ ecdev_withdraw(tp->ecdev);
+ goto err_out;
+ }
+
return 0;
err_out:
@@ -1205,17 +1174,18 @@
static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
assert (dev != NULL);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ ecdev_close(tp->ecdev);
+ ecdev_withdraw(tp->ecdev);
+ }
+ else {
unregister_netdev (dev);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
__rtl8139_cleanup_dev (dev);
pci_disable_device (pdev);
}
@@ -1416,30 +1386,19 @@
int retval;
void __iomem *ioaddr = tp->mmio_addr;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
retval = request_irq(dev->irq, rtl8139_interrupt,
SA_SHIRQ, dev->name, dev);
if (retval)
return retval;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
&tp->tx_bufs_dma);
tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
&tp->rx_ring_dma);
if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- free_irq(dev->irq, dev);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
+ if (!tp->ecdev) free_irq(dev->irq, dev);
if (tp->tx_bufs)
pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
tp->tx_bufs, tp->tx_bufs_dma);
@@ -1457,9 +1416,7 @@
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
netif_start_queue (dev);
if (netif_msg_ifup(tp))
@@ -1472,8 +1429,6 @@
rtl8139_start_thread(tp);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return 0;
}
@@ -1482,19 +1437,16 @@
{
struct rtl8139_private *tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ void __iomem *ioaddr = tp->mmio_addr;
+ uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
+ ecdev_link_state(tp->ecdev, state ? 1 : 0);
+ }
+ else {
if (tp->phys[0] >= 0) {
mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
}
- } else {
- void __iomem *ioaddr = tp->mmio_addr;
- uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
- ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
}
/* Start the hardware at open or resume. */
@@ -1559,14 +1511,9 @@
if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev)
/* Enable all known interrupts by setting the interrupt mask. */
RTL_W16 (IntrMask, rtl8139_intr_mask);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
@@ -1814,9 +1761,11 @@
if (tmp8 & CmdTxEnb)
RTL_W8 (ChipCmd, CmdRxEnb);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ rtl8139_tx_clear (tp);
+ rtl8139_hw_start (dev);
+ }
+ else {
spin_lock_bh(&tp->rx_lock);
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16 (IntrMask, 0x0000);
@@ -1832,27 +1781,19 @@
netif_wake_queue (dev);
}
spin_unlock_bh(&tp->rx_lock);
- } else {
- rtl8139_tx_clear (tp);
- rtl8139_hw_start (dev);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
}
static void rtl8139_tx_timeout (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev && !tp->have_thread) {
+ if (!tp->ecdev && !tp->have_thread) {
INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
schedule_delayed_work(&tp->thread, next_tick);
} else
tp->watchdog_fired = 1;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -1865,30 +1806,19 @@
/* Calculate the next Tx descriptor entry. */
entry = tp->cur_tx % NUM_TX_DESC;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
/* Note: the chip doesn't have auto-pad! */
if (likely(len < TX_BUF_SIZE)) {
if (len < ETH_ZLEN)
memset(tp->tx_buf[entry], 0, ETH_ZLEN);
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
- if (dev != rtl_ec_net_dev) {
- dev_kfree_skb(skb);
- }
+ if (!tp->ecdev) dev_kfree_skb(skb);
} else {
- if (dev != rtl_ec_net_dev) {
- dev_kfree_skb(skb);
- }
+ if (!tp->ecdev) dev_kfree_skb(skb);
tp->stats.tx_dropped++;
return 0;
}
- if (dev != rtl_ec_net_dev) {
- spin_lock_irq(&tp->lock);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
+ if (!tp->ecdev) spin_lock_irq(&tp->lock);
RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
@@ -1897,9 +1827,7 @@
tp->cur_tx++;
wmb();
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
if ((tp->cur_tx - NUM_TX_DESC) == tp->dirty_tx)
netif_stop_queue (dev);
spin_unlock_irq(&tp->lock);
@@ -1909,8 +1837,6 @@
dev->name, len, entry);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return 0;
}
@@ -1968,10 +1894,8 @@
tx_left--;
}
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#ifndef RTL8139_NDEBUG
- if (dev != rtl_ec_net_dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+ if (!tp->ecdev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
dev->name, dirty_tx, tp->cur_tx);
dirty_tx += NUM_TX_DESC;
@@ -1982,13 +1906,8 @@
if (tp->dirty_tx != dirty_tx) {
tp->dirty_tx = dirty_tx;
mb();
-
- if (dev != rtl_ec_net_dev) {
- netif_wake_queue (dev);
- }
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) netif_wake_queue (dev);
+ }
}
@@ -2121,15 +2040,9 @@
RTL_R16 (RxBufAddr),
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- while ((dev == rtl_ec_net_dev || netif_running(dev))
+ while ((tp->ecdev || netif_running(dev))
&& received < budget
&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
u32 ring_offset = cur_rx % RX_BUF_LEN;
u32 rx_status;
unsigned int pkt_size;
@@ -2142,17 +2055,12 @@
rx_size = rx_status >> 16;
pkt_size = rx_size - 4;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
if (netif_msg_rx_status(tp))
printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x,"
" cur %4.4x.\n", dev->name, rx_status,
rx_size, cur_rx);
}
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
#if RTL8139_DEBUG > 2
{
int i;
@@ -2200,9 +2108,14 @@
goto out;
}
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ ecdev_receive(tp->ecdev,
+ &rx_ring[ring_offset + 4], pkt_size);
+ dev->last_rx = jiffies;
+ tp->stats.rx_bytes += pkt_size;
+ tp->stats.rx_packets++;
+ }
+ else {
/* Malloc up new buffer, compatible with net-2e. */
/* Omit the four octet CRC from the length. */
@@ -2227,20 +2140,11 @@
} else {
if (net_ratelimit())
printk(KERN_WARNING
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
+ "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
tp->stats.rx_dropped++;
}
- } else {
- ecdev_receive(rtl_ec_dev,
- &rx_ring[ring_offset + 4], pkt_size);
- dev->last_rx = jiffies;
- tp->stats.rx_bytes += pkt_size;
- tp->stats.rx_packets++;
}
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
received++;
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -2346,19 +2250,15 @@
return !done;
}
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
void ec_poll(struct net_device *dev)
{
rtl8139_interrupt(0, dev, NULL);
}
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
-irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
- struct pt_regs *regs)
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
+ struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_instance;
struct rtl8139_private *tp = netdev_priv(dev);
@@ -2367,20 +2267,17 @@
int link_changed = 0; /* avoid bogus "uninit" warning */
int handled = 0;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ status = RTL_R16 (IntrStatus);
+ }
+ else {
spin_lock (&tp->lock);
status = RTL_R16 (IntrStatus);
/* shared irq? */
if (unlikely((status & rtl8139_intr_mask) == 0))
goto out;
- } else {
- status = RTL_R16 (IntrStatus);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
handled = 1;
@@ -2388,9 +2285,7 @@
if (unlikely(status == 0xFFFF))
goto out;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
/* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) {
RTL_W16 (IntrMask, 0);
@@ -2398,8 +2293,6 @@
}
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* Acknowledge all of the current interrupt sources ASAP, but
an first get an additional status bit from CSCR. */
if (unlikely(status & RxUnderrun))
@@ -2411,24 +2304,20 @@
/* Receive packets are processed by poll routine.
If not running start it now. */
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
if (status & RxAckBits){
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ /* EtherCAT device: Just receive all frames */
+ rtl8139_rx(dev, tp, 100); // FIXME
+ }
+ else {
/* Mark for polling */
if (netif_rx_schedule_prep(dev)) {
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
__netif_rx_schedule (dev);
}
- } else {
- /* EtherCAT device: Just receive all frames */
- rtl8139_rx(dev, tp, 100); // FIXME
}
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* Check uncommon events with one test. */
if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
rtl8139_weird_interrupt (dev, tp, ioaddr,
@@ -2440,14 +2329,7 @@
RTL_W16 (IntrStatus, TxErr);
}
out:
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- spin_unlock (&tp->lock);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) spin_unlock (&tp->lock);
DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
dev->name, RTL_R16 (IntrStatus));
@@ -2473,9 +2355,17 @@
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ /* Stop the chip's Tx and Rx DMA processes. */
+ RTL_W8 (ChipCmd, 0);
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ RTL_W16 (IntrMask, 0);
+
+ /* Update the error counts. */
+ tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ RTL_W32 (RxMissed, 0);
+ } else {
netif_stop_queue (dev);
rtl8139_stop_thread(tp);
@@ -2500,19 +2390,7 @@
synchronize_irq (dev->irq); /* racy, but that's ok here */
free_irq (dev->irq, dev);
- } else {
- /* Stop the chip's Tx and Rx DMA processes. */
- RTL_W8 (ChipCmd, 0);
-
- /* Disable interrupts by clearing the interrupt mask. */
- RTL_W16 (IntrMask, 0);
-
- /* Update the error counts. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
- RTL_W32 (RxMissed, 0);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
rtl8139_tx_clear (tp);
@@ -2728,13 +2606,9 @@
struct rtl8139_private *np = netdev_priv(dev);
int rc;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running(dev))
+ if (np->ecdev || !netif_running(dev))
return -EINVAL;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
spin_unlock_irq(&np->lock);
@@ -2749,17 +2623,13 @@
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || netif_running(dev)) {
+ if (tp->ecdev || netif_running(dev)) {
spin_lock_irqsave (&tp->lock, flags);
tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return &tp->stats;
}
@@ -2835,13 +2705,9 @@
pci_save_state (pdev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running (dev))
+ if (tp->ecdev || !netif_running (dev))
return 0;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
netif_device_detach (dev);
spin_lock_irqsave (&tp->lock, flags);
@@ -2865,16 +2731,11 @@
static int rtl8139_resume (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
pci_restore_state (pdev);
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running (dev))
+ if (tp->ecdev || !netif_running (dev))
return 0;
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
pci_set_power_state (pdev, PCI_D0);
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
@@ -2899,69 +2760,20 @@
static int __init rtl8139_init_module (void)
{
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- printk(KERN_INFO RTL8139_DRIVER_NAME "\n");
- printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
-
- if (pci_module_init(&rtl8139_pci_driver) < 0) {
- printk(KERN_ERR "Failed to init PCI module.\n");
- goto out_return;
- }
-
- if (rtl_ec_net_dev) {
- printk(KERN_INFO "Registering EtherCAT device...\n");
- if (!(rtl_ec_dev = ecdev_register(ec_device_master_index,
- rtl_ec_net_dev, ec_poll, THIS_MODULE))) {
- printk(KERN_ERR "Failed to register EtherCAT device!\n");
- goto out_pci;
- }
-
- printk(KERN_INFO "Opening EtherCAT device...\n");
- if (ecdev_open(rtl_ec_dev)) {
- printk(KERN_ERR "Failed to open EtherCAT device!\n");
- goto out_unregister;
- }
-
- printk(KERN_INFO "EtherCAT device ready.\n");
- } else {
- printk(KERN_WARNING "No EtherCAT device registered!\n");
- }
-
- return 0;
-
- out_unregister:
- printk(KERN_INFO "Unregistering EtherCAT device...\n");
- ecdev_unregister(ec_device_master_index, rtl_ec_dev);
- rtl_ec_dev = NULL;
- out_pci:
- pci_unregister_driver(&rtl8139_pci_driver);
- out_return:
- return -1;
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ /* when we're a module, we always print a version message,
+ * even if no 8139 board is found.
+ */
+#ifdef MODULE
+ printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
+ return pci_module_init (&rtl8139_pci_driver);
}
static void __exit rtl8139_cleanup_module (void)
{
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
-
- if (rtl_ec_net_dev) {
- printk(KERN_INFO "Closing EtherCAT device...\n");
- ecdev_close(rtl_ec_dev);
- printk(KERN_INFO "Unregistering EtherCAT device...\n");
- ecdev_unregister(ec_device_master_index, rtl_ec_dev);
- rtl_ec_dev = NULL;
- }
-
- pci_unregister_driver(&rtl8139_pci_driver);
-
- printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ pci_unregister_driver (&rtl8139_pci_driver);
}
--- a/devices/8139too-2.6.18-ethercat.c Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/8139too-2.6.18-ethercat.c Fri Feb 16 17:13:39 2007 +0000
@@ -152,8 +152,6 @@
#include <asm/uaccess.h>
#include <asm/irq.h>
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#include "../globals.h"
#include "ecdev.h"
@@ -161,8 +159,6 @@
" EtherCAT-capable Fast Ethernet driver " \
DRV_VERSION ", master " EC_MASTER_VERSION
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
#define PFX DRV_NAME ": "
/* Default Message level */
@@ -214,15 +210,6 @@
/* bitmapped message enable number */
static int debug = -1;
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-static int ec_device_index = -1;
-static int ec_device_master_index = 0;
-static ec_device_t *rtl_ec_dev;
-struct net_device *rtl_ec_net_dev = NULL;
-
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/*
* Receive ring size
* Warning: 64K ring has hardware issues and may lock up.
@@ -337,13 +324,9 @@
{0,}
};
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
/* prevent driver from being loaded automatically */
//MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
static struct {
const char str[ETH_GSTRING_LEN];
} ethtool_stats_keys[] = {
@@ -665,17 +648,15 @@
struct mii_if_info mii;
unsigned int regs_len;
unsigned long fifo_copy_timeout;
+
+ ec_device_t *ecdev;
};
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(EC_MASTER_VERSION);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
@@ -685,19 +666,8 @@
MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-module_param(ec_device_index, int, -1);
-module_param(ec_device_master_index, int, 0);
-MODULE_PARM_DESC(ec_device_index,
- "Index of the device reserved for EtherCAT.");
-MODULE_PARM_DESC(ec_device_master_index,
- "Index of the EtherCAT master to register the device.");
-
void ec_poll(struct net_device *);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
static int rtl8139_open (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location);
@@ -1051,15 +1021,6 @@
assert (dev != NULL);
tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (board_idx == ec_device_index) {
- rtl_ec_net_dev = dev;
- strcpy(dev->name, "ec0");
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
ioaddr = tp->mmio_addr;
assert (ioaddr != NULL);
@@ -1111,17 +1072,20 @@
tp->mii.reg_num_mask = 0x1f;
/* dev is fully set up and ready to use now */
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+
+ // offer device to EtherCAT master module
+ if (ecdev_offer(dev, &tp->ecdev, "8139too", board_idx,
+ ec_poll, THIS_MODULE)) {
+ printk(KERN_ERR PFX "Failed to offer device.\n");
+ goto err_out;
+ }
+
+ if (!tp->ecdev) {
DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
i = register_netdev (dev);
if (i) goto err_out;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
pci_set_drvdata (pdev, dev);
printk (KERN_INFO "%s: %s at 0x%lx, "
@@ -1194,6 +1158,11 @@
if (rtl_chip_info[tp->chipset].flags & HasHltClk)
RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */
+ if (tp->ecdev && ecdev_open(tp->ecdev)) {
+ ecdev_withdraw(tp->ecdev);
+ goto err_out;
+ }
+
return 0;
err_out:
@@ -1206,17 +1175,18 @@
static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
assert (dev != NULL);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ ecdev_close(tp->ecdev);
+ ecdev_withdraw(tp->ecdev);
+ }
+ else {
unregister_netdev (dev);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
__rtl8139_cleanup_dev (dev);
pci_disable_device (pdev);
}
@@ -1417,29 +1387,19 @@
int retval;
void __iomem *ioaddr = tp->mmio_addr;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
retval = request_irq(dev->irq, rtl8139_interrupt,
IRQF_SHARED, dev->name, dev);
if (retval)
return retval;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
&tp->tx_bufs_dma);
tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
&tp->rx_ring_dma);
if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- free_irq(dev->irq, dev);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) free_irq(dev->irq, dev);
if (tp->tx_bufs)
pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
@@ -1458,9 +1418,7 @@
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
netif_start_queue (dev);
if (netif_msg_ifup(tp))
@@ -1472,8 +1430,6 @@
rtl8139_start_thread(tp);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return 0;
}
@@ -1482,19 +1438,16 @@
{
struct rtl8139_private *tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ void __iomem *ioaddr = tp->mmio_addr;
+ uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
+ ecdev_link_state(tp->ecdev, state ? 1 : 0);
+ }
+ else {
if (tp->phys[0] >= 0) {
mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
}
- } else {
- void __iomem *ioaddr = tp->mmio_addr;
- uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
- ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
}
/* Start the hardware at open or resume. */
@@ -1559,14 +1512,9 @@
if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev)
/* Enable all known interrupts by setting the interrupt mask. */
RTL_W16 (IntrMask, rtl8139_intr_mask);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
@@ -1814,9 +1762,11 @@
if (tmp8 & CmdTxEnb)
RTL_W8 (ChipCmd, CmdRxEnb);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ rtl8139_tx_clear (tp);
+ rtl8139_hw_start (dev);
+ }
+ else {
spin_lock_bh(&tp->rx_lock);
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16 (IntrMask, 0x0000);
@@ -1832,27 +1782,19 @@
netif_wake_queue (dev);
}
spin_unlock_bh(&tp->rx_lock);
- } else {
- rtl8139_tx_clear (tp);
- rtl8139_hw_start (dev);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
}
static void rtl8139_tx_timeout (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev && !tp->have_thread) {
+ if (!tp->ecdev && !tp->have_thread) {
INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
schedule_delayed_work(&tp->thread, next_tick);
} else
tp->watchdog_fired = 1;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -1866,27 +1808,28 @@
/* Calculate the next Tx descriptor entry. */
entry = tp->cur_tx % NUM_TX_DESC;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
/* Note: the chip doesn't have auto-pad! */
if (likely(len < TX_BUF_SIZE)) {
if (len < ETH_ZLEN)
memset(tp->tx_buf[entry], 0, ETH_ZLEN);
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
- if (dev != rtl_ec_net_dev) {
- dev_kfree_skb(skb);
- }
+ if (!tp->ecdev) dev_kfree_skb(skb);
} else {
- if (dev != rtl_ec_net_dev) {
- dev_kfree_skb(skb);
- }
+ if (!tp->ecdev) dev_kfree_skb(skb);
tp->stats.tx_dropped++;
return 0;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
+ tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
+
+ dev->trans_start = jiffies;
+
+ tp->cur_tx++;
+ wmb();
+ }
+ else {
spin_lock_irqsave(&tp->lock, flags);
RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
@@ -1905,17 +1848,6 @@
printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
dev->name, len, entry);
}
- else {
- RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
- tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
-
- dev->trans_start = jiffies;
-
- tp->cur_tx++;
- wmb();
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
return 0;
}
@@ -1974,10 +1906,8 @@
tx_left--;
}
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#ifndef RTL8139_NDEBUG
- if (dev != rtl_ec_net_dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+ if (!tp->ecdev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
dev->name, dirty_tx, tp->cur_tx);
dirty_tx += NUM_TX_DESC;
@@ -1988,13 +1918,8 @@
if (tp->dirty_tx != dirty_tx) {
tp->dirty_tx = dirty_tx;
mb();
-
- if (dev != rtl_ec_net_dev) {
- netif_wake_queue (dev);
- }
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) netif_wake_queue (dev);
+ }
}
@@ -2127,14 +2052,9 @@
RTL_R16 (RxBufAddr),
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- while ((dev == rtl_ec_net_dev || netif_running(dev))
+ while ((tp->ecdev || netif_running(dev))
&& received < budget
&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
u32 ring_offset = cur_rx % RX_BUF_LEN;
u32 rx_status;
unsigned int pkt_size;
@@ -2147,17 +2067,12 @@
rx_size = rx_status >> 16;
pkt_size = rx_size - 4;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
if (netif_msg_rx_status(tp))
printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x,"
" cur %4.4x.\n", dev->name, rx_status,
rx_size, cur_rx);
}
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
#if RTL8139_DEBUG > 2
{
int i;
@@ -2205,9 +2120,14 @@
goto out;
}
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ ecdev_receive(tp->ecdev,
+ &rx_ring[ring_offset + 4], pkt_size);
+ dev->last_rx = jiffies;
+ tp->stats.rx_bytes += pkt_size;
+ tp->stats.rx_packets++;
+ }
+ else {
/* Malloc up new buffer, compatible with net-2e. */
/* Omit the four octet CRC from the length. */
@@ -2232,20 +2152,11 @@
} else {
if (net_ratelimit())
printk(KERN_WARNING
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
+ "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
tp->stats.rx_dropped++;
}
- } else {
- ecdev_receive(rtl_ec_dev,
- &rx_ring[ring_offset + 4], pkt_size);
- dev->last_rx = jiffies;
- tp->stats.rx_bytes += pkt_size;
- tp->stats.rx_packets++;
}
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
received++;
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -2351,19 +2262,15 @@
return !done;
}
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
void ec_poll(struct net_device *dev)
{
rtl8139_interrupt(0, dev, NULL);
}
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
-irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
- struct pt_regs *regs)
+static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance,
+ struct pt_regs *regs)
{
struct net_device *dev = (struct net_device *) dev_instance;
struct rtl8139_private *tp = netdev_priv(dev);
@@ -2372,20 +2279,17 @@
int link_changed = 0; /* avoid bogus "uninit" warning */
int handled = 0;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ status = RTL_R16 (IntrStatus);
+ }
+ else {
spin_lock (&tp->lock);
status = RTL_R16 (IntrStatus);
/* shared irq? */
if (unlikely((status & rtl8139_intr_mask) == 0))
goto out;
- } else {
- status = RTL_R16 (IntrStatus);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
handled = 1;
@@ -2393,9 +2297,7 @@
if (unlikely(status == 0xFFFF))
goto out;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
/* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) {
RTL_W16 (IntrMask, 0);
@@ -2403,8 +2305,6 @@
}
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* Acknowledge all of the current interrupt sources ASAP, but
an first get an additional status bit from CSCR. */
if (unlikely(status & RxUnderrun))
@@ -2416,24 +2316,20 @@
/* Receive packets are processed by poll routine.
If not running start it now. */
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
if (status & RxAckBits){
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ /* EtherCAT device: Just receive all frames */
+ rtl8139_rx(dev, tp, 100); // FIXME
+ }
+ else {
/* Mark for polling */
if (netif_rx_schedule_prep(dev)) {
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
__netif_rx_schedule (dev);
}
- } else {
- /* EtherCAT device: Just receive all frames */
- rtl8139_rx(dev, tp, 100); // FIXME
}
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* Check uncommon events with one test. */
if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
rtl8139_weird_interrupt (dev, tp, ioaddr,
@@ -2445,14 +2341,7 @@
RTL_W16 (IntrStatus, TxErr);
}
out:
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- spin_unlock (&tp->lock);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) spin_unlock (&tp->lock);
DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
dev->name, RTL_R16 (IntrStatus));
@@ -2478,9 +2367,17 @@
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ /* Stop the chip's Tx and Rx DMA processes. */
+ RTL_W8 (ChipCmd, 0);
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ RTL_W16 (IntrMask, 0);
+
+ /* Update the error counts. */
+ tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ RTL_W32 (RxMissed, 0);
+ } else {
netif_stop_queue (dev);
rtl8139_stop_thread(tp);
@@ -2505,19 +2402,7 @@
synchronize_irq (dev->irq); /* racy, but that's ok here */
free_irq (dev->irq, dev);
- } else {
- /* Stop the chip's Tx and Rx DMA processes. */
- RTL_W8 (ChipCmd, 0);
-
- /* Disable interrupts by clearing the interrupt mask. */
- RTL_W16 (IntrMask, 0);
-
- /* Update the error counts. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
- RTL_W32 (RxMissed, 0);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
rtl8139_tx_clear (tp);
@@ -2733,13 +2618,9 @@
struct rtl8139_private *np = netdev_priv(dev);
int rc;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running(dev))
+ if (np->ecdev || !netif_running(dev))
return -EINVAL;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
spin_unlock_irq(&np->lock);
@@ -2754,17 +2635,13 @@
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || netif_running(dev)) {
+ if (tp->ecdev || netif_running(dev)) {
spin_lock_irqsave (&tp->lock, flags);
tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return &tp->stats;
}
@@ -2840,13 +2717,9 @@
pci_save_state (pdev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running (dev))
+ if (tp->ecdev || !netif_running (dev))
return 0;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
netif_device_detach (dev);
spin_lock_irqsave (&tp->lock, flags);
@@ -2870,16 +2743,11 @@
static int rtl8139_resume (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
pci_restore_state (pdev);
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running (dev))
+ if (tp->ecdev || !netif_running (dev))
return 0;
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
pci_set_power_state (pdev, PCI_D0);
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
@@ -2904,69 +2772,20 @@
static int __init rtl8139_init_module (void)
{
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- printk(KERN_INFO RTL8139_DRIVER_NAME "\n");
- printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
-
- if (pci_module_init(&rtl8139_pci_driver) < 0) {
- printk(KERN_ERR "Failed to init PCI module.\n");
- goto out_return;
- }
-
- if (rtl_ec_net_dev) {
- printk(KERN_INFO "Registering EtherCAT device...\n");
- if (!(rtl_ec_dev = ecdev_register(ec_device_master_index,
- rtl_ec_net_dev, ec_poll, THIS_MODULE))) {
- printk(KERN_ERR "Failed to register EtherCAT device!\n");
- goto out_pci;
- }
-
- printk(KERN_INFO "Opening EtherCAT device...\n");
- if (ecdev_open(rtl_ec_dev)) {
- printk(KERN_ERR "Failed to open EtherCAT device!\n");
- goto out_unregister;
- }
-
- printk(KERN_INFO "EtherCAT device ready.\n");
- } else {
- printk(KERN_WARNING "No EtherCAT device registered!\n");
- }
-
- return 0;
-
- out_unregister:
- printk(KERN_INFO "Unregistering EtherCAT device...\n");
- ecdev_unregister(ec_device_master_index, rtl_ec_dev);
- rtl_ec_dev = NULL;
- out_pci:
- pci_unregister_driver(&rtl8139_pci_driver);
- out_return:
- return -1;
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ /* when we're a module, we always print a version message,
+ * even if no 8139 board is found.
+ */
+#ifdef MODULE
+ printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
+ return pci_module_init (&rtl8139_pci_driver);
}
static void __exit rtl8139_cleanup_module (void)
{
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
-
- if (rtl_ec_net_dev) {
- printk(KERN_INFO "Closing EtherCAT device...\n");
- ecdev_close(rtl_ec_dev);
- printk(KERN_INFO "Unregistering EtherCAT device...\n");
- ecdev_unregister(ec_device_master_index, rtl_ec_dev);
- rtl_ec_dev = NULL;
- }
-
- pci_unregister_driver(&rtl8139_pci_driver);
-
- printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ pci_unregister_driver (&rtl8139_pci_driver);
}
--- a/devices/8139too-2.6.19-ethercat.c Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/8139too-2.6.19-ethercat.c Fri Feb 16 17:13:39 2007 +0000
@@ -152,8 +152,6 @@
#include <asm/uaccess.h>
#include <asm/irq.h>
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#include "../globals.h"
#include "ecdev.h"
@@ -161,8 +159,6 @@
" EtherCAT-capable Fast Ethernet driver " \
DRV_VERSION ", master " EC_MASTER_VERSION
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
#define PFX DRV_NAME ": "
/* Default Message level */
@@ -214,15 +210,6 @@
/* bitmapped message enable number */
static int debug = -1;
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-static int ec_device_index = -1;
-static int ec_device_master_index = 0;
-static ec_device_t *rtl_ec_dev;
-struct net_device *rtl_ec_net_dev = NULL;
-
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/*
* Receive ring size
* Warning: 64K ring has hardware issues and may lock up.
@@ -337,13 +324,9 @@
{0,}
};
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
/* prevent driver from being loaded automatically */
//MODULE_DEVICE_TABLE (pci, rtl8139_pci_tbl);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
static struct {
const char str[ETH_GSTRING_LEN];
} ethtool_stats_keys[] = {
@@ -665,17 +648,15 @@
struct mii_if_info mii;
unsigned int regs_len;
unsigned long fifo_copy_timeout;
+
+ ec_device_t *ecdev;
};
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION("RealTek RTL-8139 EtherCAT driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(EC_MASTER_VERSION);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
module_param(multicast_filter_limit, int, 0);
module_param_array(media, int, NULL, 0);
module_param_array(full_duplex, int, NULL, 0);
@@ -685,19 +666,8 @@
MODULE_PARM_DESC (media, "8139too: Bits 4+9: force full duplex, bit 5: 100Mbps");
MODULE_PARM_DESC (full_duplex, "8139too: Force full duplex for board(s) (1)");
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
-module_param(ec_device_index, int, -1);
-module_param(ec_device_master_index, int, 0);
-MODULE_PARM_DESC(ec_device_index,
- "Index of the device reserved for EtherCAT.");
-MODULE_PARM_DESC(ec_device_master_index,
- "Index of the EtherCAT master to register the device.");
-
void ec_poll(struct net_device *);
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
static int read_eeprom (void __iomem *ioaddr, int location, int addr_len);
static int rtl8139_open (struct net_device *dev);
static int mdio_read (struct net_device *dev, int phy_id, int location);
@@ -1050,15 +1020,6 @@
assert (dev != NULL);
tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (board_idx == ec_device_index) {
- rtl_ec_net_dev = dev;
- strcpy(dev->name, "ec0");
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
ioaddr = tp->mmio_addr;
assert (ioaddr != NULL);
@@ -1110,17 +1071,20 @@
tp->mii.reg_num_mask = 0x1f;
/* dev is fully set up and ready to use now */
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+
+ // offer device to EtherCAT master module
+ if (ecdev_offer(dev, &tp->ecdev, "8139too", board_idx,
+ ec_poll, THIS_MODULE)) {
+ printk(KERN_ERR PFX "Failed to offer device.\n");
+ goto err_out;
+ }
+
+ if (!tp->ecdev) {
DPRINTK("about to register device named %s (%p)...\n", dev->name, dev);
i = register_netdev (dev);
if (i) goto err_out;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
pci_set_drvdata (pdev, dev);
printk (KERN_INFO "%s: %s at 0x%lx, "
@@ -1193,6 +1157,11 @@
if (rtl_chip_info[tp->chipset].flags & HasHltClk)
RTL_W8 (HltClk, 'H'); /* 'R' would leave the clock running. */
+ if (tp->ecdev && ecdev_open(tp->ecdev)) {
+ ecdev_withdraw(tp->ecdev);
+ goto err_out;
+ }
+
return 0;
err_out:
@@ -1205,17 +1174,18 @@
static void __devexit rtl8139_remove_one (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
assert (dev != NULL);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ ecdev_close(tp->ecdev);
+ ecdev_withdraw(tp->ecdev);
+ }
+ else {
unregister_netdev (dev);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
__rtl8139_cleanup_dev (dev);
pci_disable_device (pdev);
}
@@ -1416,29 +1386,19 @@
int retval;
void __iomem *ioaddr = tp->mmio_addr;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
retval = request_irq(dev->irq, rtl8139_interrupt,
IRQF_SHARED, dev->name, dev);
if (retval)
return retval;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
tp->tx_bufs = pci_alloc_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
&tp->tx_bufs_dma);
tp->rx_ring = pci_alloc_consistent(tp->pci_dev, RX_BUF_TOT_LEN,
&tp->rx_ring_dma);
if (tp->tx_bufs == NULL || tp->rx_ring == NULL) {
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- free_irq(dev->irq, dev);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) free_irq(dev->irq, dev);
if (tp->tx_bufs)
pci_free_consistent(tp->pci_dev, TX_BUF_TOT_LEN,
@@ -1457,9 +1417,7 @@
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
netif_start_queue (dev);
if (netif_msg_ifup(tp))
@@ -1471,8 +1429,6 @@
rtl8139_start_thread(tp);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return 0;
}
@@ -1481,19 +1437,16 @@
{
struct rtl8139_private *tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ void __iomem *ioaddr = tp->mmio_addr;
+ uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
+ ecdev_link_state(tp->ecdev, state ? 1 : 0);
+ }
+ else {
if (tp->phys[0] >= 0) {
mii_check_media(&tp->mii, netif_msg_link(tp), init_media);
}
- } else {
- void __iomem *ioaddr = tp->mmio_addr;
- uint16_t state = RTL_R16(BasicModeStatus) & BMSR_LSTATUS;
- ecdev_link_state(rtl_ec_dev, state ? 1 : 0);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
}
/* Start the hardware at open or resume. */
@@ -1558,14 +1511,9 @@
if ((!(tmp & CmdRxEnb)) || (!(tmp & CmdTxEnb)))
RTL_W8 (ChipCmd, CmdRxEnb | CmdTxEnb);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev)
/* Enable all known interrupts by setting the interrupt mask. */
RTL_W16 (IntrMask, rtl8139_intr_mask);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
@@ -1813,9 +1761,11 @@
if (tmp8 & CmdTxEnb)
RTL_W8 (ChipCmd, CmdRxEnb);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ rtl8139_tx_clear (tp);
+ rtl8139_hw_start (dev);
+ }
+ else {
spin_lock_bh(&tp->rx_lock);
/* Disable interrupts by clearing the interrupt mask. */
RTL_W16 (IntrMask, 0x0000);
@@ -1831,27 +1781,19 @@
netif_wake_queue (dev);
}
spin_unlock_bh(&tp->rx_lock);
- } else {
- rtl8139_tx_clear (tp);
- rtl8139_hw_start (dev);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
}
static void rtl8139_tx_timeout (struct net_device *dev)
{
struct rtl8139_private *tp = netdev_priv(dev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev && !tp->have_thread) {
+ if (!tp->ecdev && !tp->have_thread) {
INIT_WORK(&tp->thread, rtl8139_tx_timeout_task, dev);
schedule_delayed_work(&tp->thread, next_tick);
} else
tp->watchdog_fired = 1;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
}
static int rtl8139_start_xmit (struct sk_buff *skb, struct net_device *dev)
@@ -1865,27 +1807,28 @@
/* Calculate the next Tx descriptor entry. */
entry = tp->cur_tx % NUM_TX_DESC;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
/* Note: the chip doesn't have auto-pad! */
if (likely(len < TX_BUF_SIZE)) {
if (len < ETH_ZLEN)
memset(tp->tx_buf[entry], 0, ETH_ZLEN);
skb_copy_and_csum_dev(skb, tp->tx_buf[entry]);
- if (dev != rtl_ec_net_dev) {
- dev_kfree_skb(skb);
- }
+ if (!tp->ecdev) dev_kfree_skb(skb);
} else {
- if (dev != rtl_ec_net_dev) {
- dev_kfree_skb(skb);
- }
+ if (!tp->ecdev) dev_kfree_skb(skb);
tp->stats.tx_dropped++;
return 0;
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
+ tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
+
+ dev->trans_start = jiffies;
+
+ tp->cur_tx++;
+ wmb();
+ }
+ else {
spin_lock_irqsave(&tp->lock, flags);
RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
@@ -1904,17 +1847,6 @@
printk (KERN_DEBUG "%s: Queued Tx packet size %u to slot %d.\n",
dev->name, len, entry);
}
- else {
- RTL_W32_F (TxStatus0 + (entry * sizeof (u32)),
- tp->tx_flag | max(len, (unsigned int)ETH_ZLEN));
-
- dev->trans_start = jiffies;
-
- tp->cur_tx++;
- wmb();
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
return 0;
}
@@ -1973,10 +1905,8 @@
tx_left--;
}
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
#ifndef RTL8139_NDEBUG
- if (dev != rtl_ec_net_dev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
+ if (!tp->ecdev && tp->cur_tx - dirty_tx > NUM_TX_DESC) {
printk (KERN_ERR "%s: Out-of-sync dirty pointer, %ld vs. %ld.\n",
dev->name, dirty_tx, tp->cur_tx);
dirty_tx += NUM_TX_DESC;
@@ -1987,13 +1917,8 @@
if (tp->dirty_tx != dirty_tx) {
tp->dirty_tx = dirty_tx;
mb();
-
- if (dev != rtl_ec_net_dev) {
- netif_wake_queue (dev);
- }
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) netif_wake_queue (dev);
+ }
}
@@ -2126,14 +2051,9 @@
RTL_R16 (RxBufAddr),
RTL_R16 (RxBufPtr), RTL_R8 (ChipCmd));
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- while ((dev == rtl_ec_net_dev || netif_running(dev))
+ while ((tp->ecdev || netif_running(dev))
&& received < budget
&& (RTL_R8 (ChipCmd) & RxBufEmpty) == 0) {
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
u32 ring_offset = cur_rx % RX_BUF_LEN;
u32 rx_status;
unsigned int pkt_size;
@@ -2146,17 +2066,12 @@
rx_size = rx_status >> 16;
pkt_size = rx_size - 4;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
if (netif_msg_rx_status(tp))
printk(KERN_DEBUG "%s: rtl8139_rx() status %4.4x, size %4.4x,"
" cur %4.4x.\n", dev->name, rx_status,
rx_size, cur_rx);
}
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
#if RTL8139_DEBUG > 2
{
int i;
@@ -2204,9 +2119,14 @@
goto out;
}
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ ecdev_receive(tp->ecdev,
+ &rx_ring[ring_offset + 4], pkt_size);
+ dev->last_rx = jiffies;
+ tp->stats.rx_bytes += pkt_size;
+ tp->stats.rx_packets++;
+ }
+ else {
/* Malloc up new buffer, compatible with net-2e. */
/* Omit the four octet CRC from the length. */
@@ -2231,20 +2151,11 @@
} else {
if (net_ratelimit())
printk(KERN_WARNING
- "%s: Memory squeeze, dropping packet.\n",
- dev->name);
+ "%s: Memory squeeze, dropping packet.\n",
+ dev->name);
tp->stats.rx_dropped++;
}
- } else {
- ecdev_receive(rtl_ec_dev,
- &rx_ring[ring_offset + 4], pkt_size);
- dev->last_rx = jiffies;
- tp->stats.rx_bytes += pkt_size;
- tp->stats.rx_packets++;
}
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
received++;
cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
@@ -2350,15 +2261,11 @@
return !done;
}
-/* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
void ec_poll(struct net_device *dev)
{
rtl8139_interrupt(0, dev);
}
-/* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
static irqreturn_t rtl8139_interrupt (int irq, void *dev_instance)
@@ -2370,20 +2277,17 @@
int link_changed = 0; /* avoid bogus "uninit" warning */
int handled = 0;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ status = RTL_R16 (IntrStatus);
+ }
+ else {
spin_lock (&tp->lock);
status = RTL_R16 (IntrStatus);
/* shared irq? */
if (unlikely((status & rtl8139_intr_mask) == 0))
goto out;
- } else {
- status = RTL_R16 (IntrStatus);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
handled = 1;
@@ -2391,9 +2295,7 @@
if (unlikely(status == 0xFFFF))
goto out;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (!tp->ecdev) {
/* close possible race's with dev_close */
if (unlikely(!netif_running(dev))) {
RTL_W16 (IntrMask, 0);
@@ -2401,8 +2303,6 @@
}
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* Acknowledge all of the current interrupt sources ASAP, but
an first get an additional status bit from CSCR. */
if (unlikely(status & RxUnderrun))
@@ -2414,24 +2314,20 @@
/* Receive packets are processed by poll routine.
If not running start it now. */
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
if (status & RxAckBits){
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ /* EtherCAT device: Just receive all frames */
+ rtl8139_rx(dev, tp, 100); // FIXME
+ }
+ else {
/* Mark for polling */
if (netif_rx_schedule_prep(dev)) {
RTL_W16_F (IntrMask, rtl8139_norx_intr_mask);
__netif_rx_schedule (dev);
}
- } else {
- /* EtherCAT device: Just receive all frames */
- rtl8139_rx(dev, tp, 100); // FIXME
}
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
/* Check uncommon events with one test. */
if (unlikely(status & (PCIErr | PCSTimeout | RxUnderrun | RxErr)))
rtl8139_weird_interrupt (dev, tp, ioaddr,
@@ -2443,14 +2339,7 @@
RTL_W16 (IntrStatus, TxErr);
}
out:
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
- spin_unlock (&tp->lock);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ if (!tp->ecdev) spin_unlock (&tp->lock);
DPRINTK ("%s: exiting interrupt, intr_status=%#4.4x.\n",
dev->name, RTL_R16 (IntrStatus));
@@ -2476,9 +2365,17 @@
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev != rtl_ec_net_dev) {
+ if (tp->ecdev) {
+ /* Stop the chip's Tx and Rx DMA processes. */
+ RTL_W8 (ChipCmd, 0);
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ RTL_W16 (IntrMask, 0);
+
+ /* Update the error counts. */
+ tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
+ RTL_W32 (RxMissed, 0);
+ } else {
netif_stop_queue (dev);
rtl8139_stop_thread(tp);
@@ -2503,19 +2400,7 @@
synchronize_irq (dev->irq); /* racy, but that's ok here */
free_irq (dev->irq, dev);
- } else {
- /* Stop the chip's Tx and Rx DMA processes. */
- RTL_W8 (ChipCmd, 0);
-
- /* Disable interrupts by clearing the interrupt mask. */
- RTL_W16 (IntrMask, 0);
-
- /* Update the error counts. */
- tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
- RTL_W32 (RxMissed, 0);
- }
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ }
rtl8139_tx_clear (tp);
@@ -2731,13 +2616,9 @@
struct rtl8139_private *np = netdev_priv(dev);
int rc;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running(dev))
+ if (np->ecdev || !netif_running(dev))
return -EINVAL;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
spin_lock_irq(&np->lock);
rc = generic_mii_ioctl(&np->mii, if_mii(rq), cmd, NULL);
spin_unlock_irq(&np->lock);
@@ -2752,17 +2633,13 @@
void __iomem *ioaddr = tp->mmio_addr;
unsigned long flags;
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || netif_running(dev)) {
+ if (tp->ecdev || netif_running(dev)) {
spin_lock_irqsave (&tp->lock, flags);
tp->stats.rx_missed_errors += RTL_R32 (RxMissed);
RTL_W32 (RxMissed, 0);
spin_unlock_irqrestore (&tp->lock, flags);
}
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
return &tp->stats;
}
@@ -2835,13 +2712,9 @@
pci_save_state (pdev);
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running (dev))
+ if (tp->ecdev || !netif_running (dev))
return 0;
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
netif_device_detach (dev);
spin_lock_irqsave (&tp->lock, flags);
@@ -2865,16 +2738,11 @@
static int rtl8139_resume (struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata (pdev);
+ struct rtl8139_private *tp = netdev_priv(dev);
pci_restore_state (pdev);
-
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- if (dev == rtl_ec_net_dev || !netif_running (dev))
+ if (tp->ecdev || !netif_running (dev))
return 0;
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
-
pci_set_power_state (pdev, PCI_D0);
rtl8139_init_ring (dev);
rtl8139_hw_start (dev);
@@ -2899,69 +2767,20 @@
static int __init rtl8139_init_module (void)
{
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- printk(KERN_INFO RTL8139_DRIVER_NAME "\n");
- printk(KERN_INFO "ec_device_index is %i\n", ec_device_index);
-
- if (pci_register_driver(&rtl8139_pci_driver) < 0) {
- printk(KERN_ERR "Failed to init PCI module.\n");
- goto out_return;
- }
-
- if (rtl_ec_net_dev) {
- printk(KERN_INFO "Registering EtherCAT device...\n");
- if (!(rtl_ec_dev = ecdev_register(ec_device_master_index,
- rtl_ec_net_dev, ec_poll, THIS_MODULE))) {
- printk(KERN_ERR "Failed to register EtherCAT device!\n");
- goto out_pci;
- }
-
- printk(KERN_INFO "Opening EtherCAT device...\n");
- if (ecdev_open(rtl_ec_dev)) {
- printk(KERN_ERR "Failed to open EtherCAT device!\n");
- goto out_unregister;
- }
-
- printk(KERN_INFO "EtherCAT device ready.\n");
- } else {
- printk(KERN_WARNING "No EtherCAT device registered!\n");
- }
-
- return 0;
-
- out_unregister:
- printk(KERN_INFO "Unregistering EtherCAT device...\n");
- ecdev_unregister(ec_device_master_index, rtl_ec_dev);
- rtl_ec_dev = NULL;
- out_pci:
- pci_unregister_driver(&rtl8139_pci_driver);
- out_return:
- return -1;
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ /* when we're a module, we always print a version message,
+ * even if no 8139 board is found.
+ */
+#ifdef MODULE
+ printk (KERN_INFO RTL8139_DRIVER_NAME "\n");
+#endif
+
+ return pci_register_driver(&rtl8139_pci_driver);
}
static void __exit rtl8139_cleanup_module (void)
{
- /* EtherCAT >>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
-
- printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
-
- if (rtl_ec_net_dev) {
- printk(KERN_INFO "Closing EtherCAT device...\n");
- ecdev_close(rtl_ec_dev);
- printk(KERN_INFO "Unregistering EtherCAT device...\n");
- ecdev_unregister(ec_device_master_index, rtl_ec_dev);
- rtl_ec_dev = NULL;
- }
-
- pci_unregister_driver(&rtl8139_pci_driver);
-
- printk(KERN_INFO "RTL8139-EtherCAT module cleaned up.\n");
-
- /* EtherCAT <<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
+ pci_unregister_driver (&rtl8139_pci_driver);
}
--- a/devices/ecdev.h Fri Feb 16 13:30:46 2007 +0000
+++ b/devices/ecdev.h Fri Feb 16 17:13:39 2007 +0000
@@ -64,12 +64,12 @@
typedef void (*ec_pollfunc_t)(struct net_device *);
/*****************************************************************************/
-// Registration functions
+// Offering/withdrawal functions
-ec_device_t *ecdev_register(unsigned int master_index,
- struct net_device *net_dev, ec_pollfunc_t poll,
- struct module *module);
-void ecdev_unregister(unsigned int master_index, ec_device_t *device);
+int ecdev_offer(struct net_device *net_dev, ec_device_t **,
+ const char *driver_name, unsigned int board_index,
+ ec_pollfunc_t poll, struct module *module);
+void ecdev_withdraw(ec_device_t *device);
/*****************************************************************************/
// Device methods
--- a/master/device.h Fri Feb 16 13:30:46 2007 +0000
+++ b/master/device.h Fri Feb 16 17:13:39 2007 +0000
@@ -53,6 +53,21 @@
/*****************************************************************************/
+typedef enum {
+ ec_device_id_empty,
+ ec_device_id_mac
+}
+ec_device_id_type_t;
+
+typedef struct {
+ struct list_head list;
+ ec_device_id_type_t type;
+ unsigned char octets[ETH_ALEN];
+}
+ec_device_id_t;
+
+/*****************************************************************************/
+
/**
EtherCAT device.
An EtherCAT device is a network interface card, that is owned by an
--- a/master/master.c Fri Feb 16 13:30:46 2007 +0000
+++ b/master/master.c Fri Feb 16 17:13:39 2007 +0000
@@ -102,18 +102,20 @@
int ec_master_init(ec_master_t *master, /**< EtherCAT master */
unsigned int index, /**< master index */
+ const ec_device_id_t *main_id, /**< ID of main device */
+ const ec_device_id_t *backup_id, /**< ID of main device */
unsigned int eoeif_count /**< number of EoE interfaces */
)
{
ec_eoe_t *eoe, *next_eoe;
unsigned int i;
- EC_INFO("Initializing master %i.\n", index);
-
atomic_set(&master->available, 1);
master->index = index;
master->device = NULL;
+ master->main_device_id = main_id;
+ master->backup_device_id = backup_id;
init_MUTEX(&master->device_sem);
master->mode = EC_MASTER_MODE_ORPHANED;
--- a/master/master.h Fri Feb 16 13:30:46 2007 +0000
+++ b/master/master.h Fri Feb 16 17:13:39 2007 +0000
@@ -99,6 +99,8 @@
struct kobject kobj; /**< kobject */
ec_device_t *device; /**< EtherCAT device */
+ const ec_device_id_t *main_device_id; /**< ID of main device */
+ const ec_device_id_t *backup_device_id; /**< ID of backup device */
struct semaphore device_sem; /**< device semaphore */
ec_fsm_master_t fsm; /**< master state machine */
@@ -147,7 +149,8 @@
/*****************************************************************************/
// master creation/deletion
-int ec_master_init(ec_master_t *, unsigned int, unsigned int);
+int ec_master_init(ec_master_t *, unsigned int,
+ const ec_device_id_t *, const ec_device_id_t *, unsigned int);
void ec_master_destroy(ec_master_t *);
// mode transitions
--- a/master/module.c Fri Feb 16 13:30:46 2007 +0000
+++ b/master/module.c Fri Feb 16 17:13:39 2007 +0000
@@ -54,8 +54,12 @@
/*****************************************************************************/
-static int ec_master_count = 1; /**< parameter value, number of masters */
-static struct list_head ec_masters; /**< list of masters */
+static char *main; /**< main devices parameter */
+static char *backup; /**< backup devices parameter */
+
+static LIST_HEAD(main_device_ids); /**< list of main device IDs */
+static LIST_HEAD(backup_device_ids); /**< list of main device IDs */
+static LIST_HEAD(masters); /**< list of masters */
static dev_t device_number; /**< XML character device number */
ec_xmldev_t xmldev; /**< XML character device */
@@ -65,18 +69,171 @@
/** \cond */
-module_param(ec_master_count, int, S_IRUGO);
-
MODULE_AUTHOR("Florian Pose <fp@igh-essen.com>");
MODULE_DESCRIPTION("EtherCAT master driver module");
MODULE_LICENSE("GPL");
MODULE_VERSION(EC_MASTER_VERSION);
-MODULE_PARM_DESC(ec_master_count, "number of EtherCAT masters to initialize");
+
+module_param(main, charp, S_IRUGO);
+MODULE_PARM_DESC(main, "main device IDs");
+module_param(backup, charp, S_IRUGO);
+MODULE_PARM_DESC(backup, "backup device IDs");
/** \endcond */
/*****************************************************************************/
+void clear_device_ids(struct list_head *device_ids)
+{
+ ec_device_id_t *dev_id, *next_dev_id;
+
+ list_for_each_entry_safe(dev_id, next_dev_id, device_ids, list) {
+ list_del(&dev_id->list);
+ kfree(dev_id);
+ }
+}
+
+/*****************************************************************************/
+
+static int parse_device_id_mac(ec_device_id_t *dev_id,
+ const char *src, const char **remainder)
+{
+ unsigned int i, value;
+ char *rem;
+
+ for (i = 0; i < ETH_ALEN; i++) {
+ value = simple_strtoul(src, &rem, 16);
+ if (rem != src + 2
+ || value > 0xFF
+ || (i < ETH_ALEN - 1 && *rem != ':')) {
+ return -1;
+ }
+ dev_id->octets[i] = value;
+ if (i < ETH_ALEN - 1)
+ src = rem + 1;
+ }
+
+ dev_id->type = ec_device_id_mac;
+ *remainder = rem;
+ return 0;
+}
+
+/*****************************************************************************/
+
+static int parse_device_ids(struct list_head *device_ids, const char *src)
+{
+ const char *rem;
+ ec_device_id_t *dev_id;
+ unsigned int index = 0;
+
+ while (*src) {
+ // allocate new device ID
+ if (!(dev_id = kmalloc(sizeof(ec_device_id_t), GFP_KERNEL))) {
+ EC_ERR("Out of memory!\n");
+ goto out_free;
+ }
+
+ if (*src == ';') { // empty device ID
+ dev_id->type = ec_device_id_empty;
+ }
+ else if (*src == 'M') {
+ src++;
+ if (parse_device_id_mac(dev_id, src, &rem)) {
+ EC_ERR("Device ID %u: Invalid MAC syntax!\n", index);
+ kfree(dev_id);
+ goto out_free;
+ }
+ src = rem;
+ }
+ else {
+ EC_ERR("Device ID %u: Unknown format \'%c\'!\n", index, *src);
+ kfree(dev_id);
+ goto out_free;
+ }
+
+ list_add_tail(&dev_id->list, device_ids);
+ if (*src) {
+ if (*src != ';') {
+ EC_ERR("Invalid delimiter '%c' after device ID %i!\n",
+ *src, index);
+ goto out_free;
+ }
+ src++; // skip delimiter
+ }
+ index++;
+ }
+
+ return 0;
+
+out_free:
+ clear_device_ids(device_ids);
+ return -1;
+}
+
+/*****************************************************************************/
+
+static int create_device_ids(void)
+{
+ ec_device_id_t *id;
+ unsigned int main_count = 0, backup_count = 0;
+
+ if (parse_device_ids(&main_device_ids, main))
+ return -1;
+
+ if (parse_device_ids(&backup_device_ids, main))
+ return -1;
+
+ // count main device IDs and check for empty ones
+ list_for_each_entry(id, &main_device_ids, list) {
+ if (id->type == ec_device_id_empty) {
+ EC_ERR("Main device IDs may not be empty!\n");
+ return -1;
+ }
+ main_count++;
+ }
+
+ // count backup device IDs
+ list_for_each_entry(id, &backup_device_ids, list) {
+ backup_count++;
+ }
+
+ // fill up backup device IDs
+ while (backup_count < main_count) {
+ if (!(id = kmalloc(sizeof(ec_device_id_t), GFP_KERNEL))) {
+ EC_ERR("Out of memory!\n");
+ return -1;
+ }
+
+ id->type = ec_device_id_empty;
+ list_add_tail(&id->list, &backup_device_ids);
+ backup_count++;
+ }
+
+ return 0;
+}
+
+/*****************************************************************************/
+
+static int device_id_check(const ec_device_id_t *dev_id,
+ const struct net_device *dev, const char *driver_name,
+ unsigned int device_index)
+{
+ unsigned int i;
+
+ switch (dev_id->type) {
+ case ec_device_id_mac:
+ for (i = 0; i < ETH_ALEN; i++)
+ if (dev->dev_addr[i] != dev_id->octets[i])
+ return 0;
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+/*****************************************************************************/
+
/**
Module initialization.
Initializes \a ec_master_count masters.
@@ -85,48 +242,68 @@
int __init ec_init_module(void)
{
- unsigned int i;
ec_master_t *master, *next;
+ ec_device_id_t *main_dev_id, *backup_dev_id;
+ unsigned int master_index = 0;
EC_INFO("Master driver %s\n", EC_MASTER_VERSION);
- if (ec_master_count < 1) {
- EC_ERR("Invalid ec_master_count: %i\n", ec_master_count);
+ if (alloc_chrdev_region(&device_number, 0, 1, "EtherCAT")) {
+ EC_ERR("Failed to obtain device number!\n");
goto out_return;
}
- if (alloc_chrdev_region(&device_number, 0, ec_master_count, "EtherCAT")) {
- EC_ERR("Failed to allocate device number!\n");
- goto out_return;
- }
-
- EC_INFO("Initializing %i EtherCAT master(s)...\n", ec_master_count);
-
- INIT_LIST_HEAD(&ec_masters);
-
- for (i = 0; i < ec_master_count; i++) {
- if (!(master =
- (ec_master_t *) kmalloc(sizeof(ec_master_t), GFP_KERNEL))) {
- EC_ERR("Failed to allocate memory for EtherCAT master %i.\n", i);
- goto out_free;
- }
-
- if (ec_master_init(master, i, 0))
- goto out_free;
-
- list_add_tail(&master->list, &ec_masters);
- }
-
- EC_INFO("Master driver initialized.\n");
+ if (create_device_ids())
+ goto out_free_ids;
+
+ if (!list_empty(&main_device_ids)) {
+ main_dev_id =
+ list_entry(main_device_ids.next, ec_device_id_t, list);
+ backup_dev_id =
+ list_entry(backup_device_ids.next, ec_device_id_t, list);
+
+ while (1) {
+ if (!(master = (ec_master_t *)
+ kmalloc(sizeof(ec_master_t), GFP_KERNEL))) {
+ EC_ERR("Failed to allocate memory for EtherCAT master %i.\n",
+ master_index);
+ goto out_free_masters;
+ }
+
+ if (ec_master_init(master, master_index,
+ main_dev_id, backup_dev_id, 0))
+ goto out_free_masters;
+
+ list_add_tail(&master->list, &masters);
+ master_index++;
+
+ // last device IDs?
+ if (main_dev_id->list.next == &main_device_ids)
+ break;
+
+ // next device IDs
+ main_dev_id =
+ list_entry(main_dev_id->list.next, ec_device_id_t, list);
+ backup_dev_id =
+ list_entry(backup_dev_id->list.next, ec_device_id_t, list);
+ }
+ }
+
+ EC_INFO("%u master%s waiting for devices.\n",
+ master_index, (master_index == 1 ? "" : "s"));
return 0;
- out_free:
- list_for_each_entry_safe(master, next, &ec_masters, list) {
+out_free_masters:
+ list_for_each_entry_safe(master, next, &masters, list) {
list_del(&master->list);
kobject_del(&master->kobj);
kobject_put(&master->kobj);
}
- out_return:
+out_free_ids:
+ clear_device_ids(&main_device_ids);
+ clear_device_ids(&backup_device_ids);
+ unregister_chrdev_region(device_number, 1);
+out_return:
return -1;
}
@@ -143,12 +320,12 @@
EC_INFO("Cleaning up master driver...\n");
- list_for_each_entry_safe(master, next, &ec_masters, list) {
+ list_for_each_entry_safe(master, next, &masters, list) {
list_del(&master->list);
ec_master_destroy(master);
}
- unregister_chrdev_region(device_number, ec_master_count);
+ unregister_chrdev_region(device_number, 1);
EC_INFO("Master driver cleaned up.\n");
}
@@ -164,7 +341,7 @@
{
ec_master_t *master;
- list_for_each_entry(master, &ec_masters, list) {
+ list_for_each_entry(master, &masters, list) {
if (master->index == master_index) return master;
}
@@ -270,48 +447,71 @@
*****************************************************************************/
/**
- Connects an EtherCAT device to a certain master.
- The master will use the device for sending and receiving frames. It is
- required that no other instance (for example the kernel IP stack) uses
- the device.
+ Offers an EtherCAT device to a certain master.
+ The master decides, if it wants to use the device for EtherCAT operation,
+ or not. It is important, that the offered net_device is not used by
+ the kernel IP stack. If the master, accepted the offer, the address of
+ the newly created EtherCAT device is written to the ecdev pointer, else
+ the pointer is written to zero.
\return 0 on success, else < 0
\ingroup DeviceInterface
*/
-ec_device_t *ecdev_register(unsigned int master_index, /**< master index */
- struct net_device *net_dev, /**< net_device of
- the device */
- ec_pollfunc_t poll, /**< device poll function */
- struct module *module /**< pointer to the module */
- )
+int ecdev_offer(struct net_device *net_dev, /**< net_device to offer */
+ ec_device_t **ecdev, /**< pointer to store a device on success */
+ const char *driver_name, /**< name of the network driver */
+ unsigned int device_index, /**< index of the supported device */
+ ec_pollfunc_t poll, /**< device poll function */
+ struct module *module /**< pointer to the module */
+ )
{
ec_master_t *master;
-
- if (!(master = ec_find_master(master_index))) return NULL;
-
- if (down_interruptible(&master->device_sem)) {
- EC_ERR("Interrupted while waiting for device!\n");
- goto out_return;
- }
-
- if (master->device) {
- EC_ERR("Master %i already has a device!\n", master_index);
- goto out_up;
- }
-
- if (!(master->device =
- (ec_device_t *) kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
- EC_ERR("Failed to allocate device!\n");
- goto out_up;
- }
-
- if (ec_device_init(master->device, master, net_dev, poll, module)) {
- EC_ERR("Failed to init device!\n");
- goto out_free;
- }
-
- up(&master->device_sem);
- return master->device;
+ unsigned int i;
+
+ list_for_each_entry(master, &masters, list) {
+ if (down_interruptible(&master->device_sem)) {
+ EC_ERR("Interrupted while waiting for device semaphore!\n");
+ goto out_return;
+ }
+
+ if (device_id_check(master->main_device_id, net_dev,
+ driver_name, device_index)) {
+
+ EC_INFO("Accepting device %s:%u (", driver_name, device_index);
+ for (i = 0; i < ETH_ALEN; i++) {
+ printk("%02X", net_dev->dev_addr[i]);
+ if (i < ETH_ALEN - 1) printk(":");
+ }
+ printk(") for master %u.\n", master->index);
+
+ if (master->device) {
+ EC_ERR("Master already has a device.\n");
+ goto out_up;
+ }
+
+ if (!(master->device = (ec_device_t *)
+ kmalloc(sizeof(ec_device_t), GFP_KERNEL))) {
+ EC_ERR("Failed to allocate device!\n");
+ goto out_up;
+ }
+
+ if (ec_device_init(master->device, master,
+ net_dev, poll, module)) {
+ EC_ERR("Failed to init device!\n");
+ goto out_free;
+ }
+
+ up(&master->device_sem);
+ sprintf(net_dev->name, "ec%u", master->index);
+ *ecdev = master->device; // offer accepted
+ return 0; // no error
+ }
+
+ up(&master->device_sem);
+ }
+
+ *ecdev = NULL; // offer declined
+ return 0; // no error
out_free:
kfree(master->device);
@@ -319,13 +519,13 @@
out_up:
up(&master->device_sem);
out_return:
- return NULL;
-}
-
-/*****************************************************************************/
-
-/**
- Disconnect an EtherCAT device from the master.
+ return 1;
+}
+
+/*****************************************************************************/
+
+/**
+ Withdraws an EtherCAT device from the master.
The device is disconnected from the master and all device ressources
are freed.
\attention Before calling this function, the ecdev_stop() function has
@@ -333,26 +533,24 @@
\ingroup DeviceInterface
*/
-void ecdev_unregister(unsigned int master_index, /**< master index */
- ec_device_t *device /**< EtherCAT device */
- )
-{
- ec_master_t *master;
-
- if (!(master = ec_find_master(master_index))) return;
+void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
+{
+ ec_master_t *master = device->master;
+ unsigned int i;
down(&master->device_sem);
-
- if (!master->device || master->device != device) {
- up(&master->device_sem);
- EC_WARN("Unable to unregister device!\n");
- return;
- }
-
+
+ EC_INFO("Master %u releasing device ", master->index);
+ for (i = 0; i < ETH_ALEN; i++) {
+ printk("%02X", device->dev->dev_addr[i]);
+ if (i < ETH_ALEN - 1) printk(":");
+ }
+ printk(".\n");
+
ec_device_clear(master->device);
kfree(master->device);
master->device = NULL;
-
+
up(&master->device_sem);
}
@@ -505,8 +703,8 @@
module_init(ec_init_module);
module_exit(ec_cleanup_module);
-EXPORT_SYMBOL(ecdev_register);
-EXPORT_SYMBOL(ecdev_unregister);
+EXPORT_SYMBOL(ecdev_offer);
+EXPORT_SYMBOL(ecdev_withdraw);
EXPORT_SYMBOL(ecdev_open);
EXPORT_SYMBOL(ecdev_close);
EXPORT_SYMBOL(ecrt_request_master);
--- a/script/init.d/ethercat Fri Feb 16 13:30:46 2007 +0000
+++ b/script/init.d/ethercat Fri Feb 16 17:13:39 2007 +0000
@@ -49,100 +49,39 @@
#------------------------------------------------------------------------------
-device="ecxml"
-
-IFCONFIG=ifconfig
-BRCTL=brctl
-ROUTE=route
+XMLDEVICE='ecxml'
#------------------------------------------------------------------------------
ETHERCAT_CONFIG=/etc/sysconfig/ethercat
-if [ ! -r $ETHERCAT_CONFIG ]; then
- echo "$ETHERCAT_CONFIG not existing";
- if [ "$1" = "stop" ]; then
+if [ ! -r ${ETHERCAT_CONFIG} ]; then
+ echo "${ETHERCAT_CONFIG} not existing";
+ if [ "${1}" = "stop" ]; then
exit 0
else
exit 6
fi
fi
-. $ETHERCAT_CONFIG
-
-#------------------------------------------------------------------------------
-
-#
-# Function for setting up the EoE bridge
-#
-build_eoe_bridge()
+. ${ETHERCAT_CONFIG}
+
+#------------------------------------------------------------------------------
+
+function make_device_id()
{
- if [ -z "$EOE_BRIDGE" ]; then return; fi
-
- EOEIF=`$IFCONFIG -a | grep -o -E "^eoe[0-9]+ "`
-
- # add bridge, if it does not already exist
- if ! $BRCTL show | grep -E -q "^$EOE_BRIDGE"; then
- if ! $BRCTL addbr $EOE_BRIDGE; then
- /bin/false
- rc_status -v
- rc_exit
- fi
- fi
-
- # check if specified interfaces are bridged
- for interf in $EOEIF $EOE_EXTRA_INTERFACES; do
- # interface is already part of the bridge (FIXME->show $EOE_BRIDGE)
- if $BRCTL show | grep -E -q $interf
- then continue
- fi
- # clear IP address and open interface
- if ! $IFCONFIG $interf 0.0.0.0 up; then
- /bin/false
- rc_status -v
- rc_exit
- fi
- # add interface to the bridge
- if ! $BRCTL addif $EOE_BRIDGE $interf; then
- /bin/false
- rc_status -v
- rc_exit
- fi
- done
-
- # configure IP on bridge
- if [ -n "$EOE_IP_ADDRESS" -a -n "$EOE_IP_NETMASK" ]; then
- if ! $IFCONFIG $EOE_BRIDGE $EOE_IP_ADDRESS \
- netmask $EOE_IP_NETMASK; then
- /bin/false
- rc_status -v
- rc_exit
- fi
- fi
-
- # open bridge
- if ! $IFCONFIG $EOE_BRIDGE up; then
- /bin/false
- rc_status -v
- rc_exit
- fi
-
- # install new default gateway
- if [ -n "$EOE_GATEWAY" ]; then
- while $ROUTE -n | grep -E -q "^0.0.0.0"; do
- if ! $ROUTE del default; then
- echo "Failed to remove route!" 1>&2
- /bin/false
- rc_status -v
- rc_exit
- fi
- done
- if ! $ROUTE add default gw $EOE_GATEWAY; then
- /bin/false
- rc_status -v
- rc_exit
- fi
- fi
+ if [ -z "${1}" ]; then
+ DEVICE_ID=";"
+ elif echo ${1} | grep -qE '^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$'; then
+ DEVICE_ID="M${1};"
+ elif echo ${1} | grep -qE '^[^:]+:[0-9]+$'; then
+ DEVICE_ID="D${1};"
+ else
+ echo Invalid device ID syntax in ${ETHERCAT_CONFIG}
+ /bin/false
+ rc_status -v
+ rc_exit
+ fi
}
#------------------------------------------------------------------------------
@@ -150,127 +89,119 @@
. /etc/rc.status
rc_reset
-case "$1" in
-
- start)
- echo -n "Starting EtherCAT master "
-
- if [ -z "$DEVICE_INDEX" ]; then
- echo "ERROR: DEVICE_INDEX not set!"
- /bin/false
- rc_status -v
- rc_exit
- fi
-
- if [ -z "$EOE_INTERFACES" ]; then
- # support legacy sysconfig files
- if [ -n "$EOE_DEVICES" ]; then
- EOE_INTERFACES=$EOE_DEVICES
- else
- EOE_INTERFACES=0
- fi
- fi
-
- # unload conflicting modules at first
- for mod in 8139too; do
- if lsmod | grep "^$mod " > /dev/null; then
- if ! rmmod $mod; then
- /bin/false
- rc_status -v
- rc_exit
- fi
- fi
- done
-
- # load master module
- if ! modprobe ec_master ec_eoeif_count=$EOE_INTERFACES; then
- modprobe 8139too
- /bin/false
- rc_status -v
- rc_exit
- fi
-
- # remove stale device node
- rm -f /dev/${device}0
-
- # get dynamic major number
- major=$(awk "\$2==\"EtherCAT\" {print \$1}" /proc/devices)
-
- # create character device
- mknod /dev/${device}0 c $major 0
-
- # load device module
- if ! modprobe ec_8139too ec_device_index=$DEVICE_INDEX; then
- rmmod ec_master
- modprobe 8139too
- /bin/false
- rc_status -v
- rc_exit
- fi
-
- # build EoE bridge
- build_eoe_bridge
-
- rc_status -v
- ;;
-
- stop)
- echo -n "Shutting down EtherCAT master "
-
- # unload modules
- for mod in ec_8139too ec_master; do
- if lsmod | grep "^$mod " > /dev/null; then
- if ! rmmod $mod; then
- /bin/false
- rc_status -v
- rc_exit
- fi;
- fi;
- done
-
- # remove device node
- rm -f /dev/${device}0
-
- sleep 1
-
- # reload previous modules
- if ! modprobe 8139too; then
- echo "Warning: Failed to restore 8139too module."
- fi
-
- rc_status -v
- ;;
-
- restart)
- $0 stop || exit 1
- sleep 1
- $0 start
- rc_status
- ;;
-
- status)
- echo -n "Checking for EtherCAT "
-
- lsmod | grep "^ec_master " > /dev/null
- master_running=$?
- lsmod | grep "^ec_8139too " > /dev/null
- device_running=$?
-
- # master module and device module loaded?
- test $master_running -eq 0 -a $device_running -eq 0
-
- rc_status -v
- ;;
-
- bridge)
- echo -n "Building EoE bridge "
- build_eoe_bridge
- rc_status -v
- ;;
-
- *)
- echo "USAGE: $0 {start|stop|restart|status|bridge}"
- ;;
+case "${1}" in
+
+start)
+ echo -n "Starting EtherCAT master "
+
+ # construct DEVICES and BACKUPS from configuration variables
+ DEVICES=""
+ BACKUPS=""
+ MASTER_INDEX=0
+ while true; do
+ DEVICE=$(eval echo "\${MASTER${MASTER_INDEX}_DEVICE}")
+ BACKUP=$(eval echo "\${MASTER${MASTER_INDEX}_BACKUP}")
+ if [ -z "${DEVICE}" ]; then break; fi
+
+ make_device_id ${DEVICE}
+ DEVICES=${DEVICES}${DEVICE_ID}
+ make_device_id ${BACKUP}
+ BACKUPS=${BACKUPS}${DEVICE_ID}
+
+ MASTER_INDEX=$(expr ${MASTER_INDEX} + 1)
+ done
+
+ # unload conflicting modules at first
+ for MODULE in 8139too; do
+ if lsmod | grep "^${MODULE} " > /dev/null; then
+ if ! rmmod ${MODULE}; then
+ /bin/false
+ rc_status -v
+ rc_exit
+ fi
+ fi
+ done
+
+ # load master module
+ if ! modprobe ec_master main=${DEVICES} backup=${BACKUPS}; then
+ modprobe 8139too
+ /bin/false
+ rc_status -v
+ rc_exit
+ fi
+
+ # remove stale device node
+ rm -f /dev/${XMLDEVICE}0
+
+ # get dynamic major number
+ MAJOR=$(awk "\$2==\"EtherCAT\" {print \$1}" /proc/devices)
+
+ # create character device
+ mknod /dev/${XMLDEVICE}0 c ${MAJOR} 0
+
+ # load device module
+ if ! modprobe ec_8139too; then
+ rmmod ec_master
+ modprobe 8139too
+ /bin/false
+ rc_status -v
+ rc_exit
+ fi
+
+ rc_status -v
+ ;;
+
+stop)
+ echo -n "Shutting down EtherCAT master "
+
+ # unload modules
+ for mod in ec_8139too ec_master; do
+ if lsmod | grep "^$mod " > /dev/null; then
+ if ! rmmod $mod; then
+ /bin/false
+ rc_status -v
+ rc_exit
+ fi;
+ fi;
+ done
+
+ # remove device node
+ rm -f /dev/${XMLDEVICE}0
+
+ sleep 1
+
+ # reload previous modules
+ if ! modprobe 8139too; then
+ echo "Warning: Failed to restore 8139too module."
+ fi
+
+ rc_status -v
+ ;;
+
+restart)
+ $0 stop || exit 1
+ sleep 1
+ $0 start
+ rc_status
+ ;;
+
+status)
+ echo -n "Checking for EtherCAT "
+
+ lsmod | grep "^ec_master " > /dev/null
+ master_running=$?
+ lsmod | grep "^ec_8139too " > /dev/null
+ device_running=$?
+
+ # master module and device module loaded?
+ test $master_running -eq 0 -a $device_running -eq 0
+
+ rc_status -v
+ ;;
+
+*)
+ echo "USAGE: $0 {start|stop|restart|status}"
+ ;;
esac
--- a/script/sysconfig/ethercat Fri Feb 16 13:30:46 2007 +0000
+++ b/script/sysconfig/ethercat Fri Feb 16 17:13:39 2007 +0000
@@ -1,58 +1,32 @@
#------------------------------------------------------------------------------
#
-# EtherCAT sysconfig file
+# EtherCAT master sysconfig file
#
# $Id$
#
#------------------------------------------------------------------------------
#
-# PCI index of the (RTL8139-)EtherCAT device
-# Setting this is mandatory for the EtherCAT init script!
+# Master device and backup-device settings.
#
-#DEVICE_INDEX=99
-
+# The MASTERX_DEVICE variable specifies the ethernet device for master 'X',
+# while the MASTERX_BACKUP variable specifies the backup ethernet device for
+# redundancy purposes.
#
-# Number of Ethernet-over-EtherCAT interfaces every master shall create
-# on startup. Default is 0.
+# There are three formats for specifying ethernet devices:
+# 1) MAC address (example: "00:00:08:44:55:66"). Specify the MAC address of
+# the ethernet card to use.
+# 2) PCI bus address (example: "01:1c.0"). Specify the PCU bis address of the
+# ethernet card to use.
+# 3) Driver and device index (example: "8139too:0"). Currently there are two
+# drivers available: "8139too" and "e100". The device index is the index
+# into driver-supported PCI cards.
#
-#EOE_INTERFACES=0
-
+# The MASTERX_DEVICE variables also determine, how many masters will be
+# created: A non-empty variable MASTER0_DEVICE will create one master, adding
+# a non-empty variable MASTER1_DEVICE will create a second master, and so on.
#
-# Bridge all EoE interfaces after master startup
-# This variable shall contain the name of the EoE bridge to set up.
-# If the variable is empty or undefined, no EoE bridge will be built.
-#
-#EOE_BRIDGE=eoebr0
-
-#
-# IP address of the EoE bridge
-# Set both EOE_IP_ADDRESS and EOE_IP_NETMASK to let the local host communicate
-# with devices on the EoE bridge.
-#
-#EOE_IP_ADDRESS=192.168.X.X
-
-#
-# IP netmask of the EoE bridge
-# See EOE_IP_ADDRESS.
-#
-#EOE_IP_NETMASK=255.255.255.0
-
-#
-# Renew default gateway after bridge installation.
-# Set this to the new default gateway, if the default route shall
-# be renewed after the bridge has been installed.
-#
-#EOE_GATEWAY=192.168.X.X
-
-#
-# List of extra interfaces to include in the EoE bridge.
-# Set this to interconnect the EoE bridge with other local interfaces.
-# If EOE_BRIDGE is empty or undefined, setting this variable has no effect.
-# Important: The IP address of these interfaces will be cleared. Set
-# EOE_IP_ADDRESS and EOE_IP_NETMASK accordingly to enable IP traffic to
-# extra interfaces.
-#
-#EOE_EXTRA_INTERFACES=eth0
+MASTER0_DEVICE=
+MASTER0_BACKUP=
#------------------------------------------------------------------------------