--- a/devices/forcedeth-2.6.17-ethercat.c Thu Feb 22 09:34:32 2007 +0000
+++ b/devices/forcedeth-2.6.17-ethercat.c Thu Feb 22 10:06:32 2007 +0000
@@ -607,7 +607,6 @@
struct msix_entry msi_x_entry[NV_MSI_X_MAX_VECTORS];
ec_device_t *ecdev;
- u8 rx_data[ETH_FRAME_LEN];
};
/*
@@ -1251,7 +1250,7 @@
spin_unlock_irq(&np->lock);
netif_stop_queue(dev);
return NETDEV_TX_BUSY;
- }
+ }
}
/* setup the header buffer */
@@ -1592,6 +1591,7 @@
pci_unmap_single(np->pci_dev, np->rx_dma[i],
np->rx_skbuff[i]->end-np->rx_skbuff[i]->data,
PCI_DMA_FROMDEVICE);
+
{
int j;
dprintk(KERN_DEBUG "Dumping packet (flags 0x%x).",Flags);
@@ -1695,7 +1695,7 @@
skb_put(skb, len);
skb->protocol = eth_type_trans(skb, dev);
dprintk(KERN_DEBUG "%s: nv_rx_process: packet %d with %d bytes, proto %d accepted.\n",
- dev->name, np->cur_rx, len, skb->protocol);
+ dev->name, np->cur_rx, len, skb->protocol);
if (np->vlangrp && (vlanflags & NV_RX3_VLAN_TAG_PRESENT)) {
vlan_hwaccel_rx(skb, np->vlangrp, vlanflags & NV_RX3_VLAN_TAG_MASK);
} else {
@@ -2052,7 +2052,8 @@
struct fe_priv *np = netdev_priv(dev);
if (np->ecdev) {
- nv_update_linkspeed(dev);
+ int link = nv_update_linkspeed(dev);
+ ecdev_link_state(np->ecdev, link);
return;
}
@@ -2108,9 +2109,9 @@
if (!(events & np->irqmask))
break;
- spin_lock(&np->lock);
+ if (!np->ecdev) spin_lock(&np->lock);
nv_tx_done(dev);
- spin_unlock(&np->lock);
+ if (!np->ecdev) spin_unlock(&np->lock);
nv_rx_process(dev);
if (nv_alloc_rx(dev)) {
@@ -2121,14 +2122,14 @@
}
if (events & NVREG_IRQ_LINK) {
- spin_lock(&np->lock);
+ if (!np->ecdev) spin_lock(&np->lock);
nv_link_irq(dev);
- spin_unlock(&np->lock);
+ if (!np->ecdev) spin_unlock(&np->lock);
}
if (np->need_linktimer && time_after(jiffies, np->link_timeout)) {
- spin_lock(&np->lock);
+ if (!np->ecdev) spin_lock(&np->lock);
nv_linkchange(dev);
- spin_unlock(&np->lock);
+ if (!np->ecdev) spin_unlock(&np->lock);
np->link_timeout = jiffies + LINK_TIMEOUT;
}
if (events & (NVREG_IRQ_TX_ERR)) {
@@ -2140,20 +2141,22 @@
dev->name, events);
}
if (i > max_interrupt_work) {
- spin_lock(&np->lock);
- /* disable interrupts on the nic */
- if (!(np->msi_flags & NV_MSI_X_ENABLED))
- writel(0, base + NvRegIrqMask);
- else
- writel(np->irqmask, base + NvRegIrqMask);
- pci_push(base);
-
- if (!np->in_shutdown) {
- np->nic_poll_irq = np->irqmask;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ if (!np->ecdev) {
+ spin_lock(&np->lock);
+ /* disable interrupts on the nic */
+ if (!(np->msi_flags & NV_MSI_X_ENABLED))
+ writel(0, base + NvRegIrqMask);
+ else
+ writel(np->irqmask, base + NvRegIrqMask);
+ pci_push(base);
+
+ if (!np->in_shutdown) {
+ np->nic_poll_irq = np->irqmask;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock(&np->lock);
}
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq.\n", dev->name, i);
- spin_unlock(&np->lock);
break;
}
@@ -2181,26 +2184,28 @@
if (!(events & np->irqmask))
break;
- spin_lock_irq(&np->lock);
+ if (!np->ecdev) spin_lock_irq(&np->lock);
nv_tx_done(dev);
- spin_unlock_irq(&np->lock);
+ if (!np->ecdev) spin_unlock_irq(&np->lock);
if (events & (NVREG_IRQ_TX_ERR)) {
dprintk(KERN_DEBUG "%s: received irq with events 0x%x. Probably TX fail.\n",
dev->name, events);
}
if (i > max_interrupt_work) {
- spin_lock_irq(&np->lock);
- /* disable interrupts on the nic */
- writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask);
- pci_push(base);
-
- if (!np->in_shutdown) {
- np->nic_poll_irq |= NVREG_IRQ_TX_ALL;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ if (!np->ecdev) {
+ spin_lock_irq(&np->lock);
+ /* disable interrupts on the nic */
+ writel(NVREG_IRQ_TX_ALL, base + NvRegIrqMask);
+ pci_push(base);
+
+ if (!np->in_shutdown) {
+ np->nic_poll_irq |= NVREG_IRQ_TX_ALL;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock_irq(&np->lock);
}
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_tx.\n", dev->name, i);
- spin_unlock_irq(&np->lock);
break;
}
@@ -2229,7 +2234,7 @@
break;
nv_rx_process(dev);
- if (nv_alloc_rx(dev)) {
+ if (nv_alloc_rx(dev) && !np->ecdev) {
spin_lock_irq(&np->lock);
if (!np->in_shutdown)
mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
@@ -2237,17 +2242,19 @@
}
if (i > max_interrupt_work) {
- spin_lock_irq(&np->lock);
- /* disable interrupts on the nic */
- writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
- pci_push(base);
-
- if (!np->in_shutdown) {
- np->nic_poll_irq |= NVREG_IRQ_RX_ALL;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ if (!np->ecdev) {
+ spin_lock_irq(&np->lock);
+ /* disable interrupts on the nic */
+ writel(NVREG_IRQ_RX_ALL, base + NvRegIrqMask);
+ pci_push(base);
+
+ if (!np->in_shutdown) {
+ np->nic_poll_irq |= NVREG_IRQ_RX_ALL;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock_irq(&np->lock);
}
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_rx.\n", dev->name, i);
- spin_unlock_irq(&np->lock);
break;
}
@@ -2276,14 +2283,14 @@
break;
if (events & NVREG_IRQ_LINK) {
- spin_lock_irq(&np->lock);
+ if (!np->ecdev) spin_lock_irq(&np->lock);
nv_link_irq(dev);
- spin_unlock_irq(&np->lock);
+ if (!np->ecdev) spin_unlock_irq(&np->lock);
}
if (np->need_linktimer && time_after(jiffies, np->link_timeout)) {
- spin_lock_irq(&np->lock);
+ if (!np->ecdev) spin_lock_irq(&np->lock);
nv_linkchange(dev);
- spin_unlock_irq(&np->lock);
+ if (!np->ecdev) spin_unlock_irq(&np->lock);
np->link_timeout = jiffies + LINK_TIMEOUT;
}
if (events & (NVREG_IRQ_UNKNOWN)) {
@@ -2291,17 +2298,19 @@
dev->name, events);
}
if (i > max_interrupt_work) {
- spin_lock_irq(&np->lock);
- /* disable interrupts on the nic */
- writel(NVREG_IRQ_OTHER, base + NvRegIrqMask);
- pci_push(base);
-
- if (!np->in_shutdown) {
- np->nic_poll_irq |= NVREG_IRQ_OTHER;
- mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ if (!np->ecdev) {
+ spin_lock_irq(&np->lock);
+ /* disable interrupts on the nic */
+ writel(NVREG_IRQ_OTHER, base + NvRegIrqMask);
+ pci_push(base);
+
+ if (!np->in_shutdown) {
+ np->nic_poll_irq |= NVREG_IRQ_OTHER;
+ mod_timer(&np->nic_poll, jiffies + POLL_WAIT);
+ }
+ spin_unlock_irq(&np->lock);
}
printk(KERN_DEBUG "%s: too many iterations (%d) in nv_nic_irq_other.\n", dev->name, i);
- spin_unlock_irq(&np->lock);
break;
}
@@ -2313,7 +2322,21 @@
void ec_poll(struct net_device *dev)
{
- nv_nic_irq((int) 0, dev, (struct pt_regs *) NULL);
+ struct fe_priv *np = netdev_priv(dev);
+
+ if (!using_multi_irqs(dev)) {
+ nv_nic_irq((int) 0, dev, (struct pt_regs *) NULL);
+ } else {
+ if (np->nic_poll_irq & NVREG_IRQ_RX_ALL) {
+ nv_nic_irq_rx((int) 0, dev, (struct pt_regs *) NULL);
+ }
+ if (np->nic_poll_irq & NVREG_IRQ_TX_ALL) {
+ nv_nic_irq_tx((int) 0, dev, (struct pt_regs *) NULL);
+ }
+ if (np->nic_poll_irq & NVREG_IRQ_OTHER) {
+ nv_nic_irq_other((int) 0, dev, (struct pt_regs *) NULL);
+ }
+ }
}
static void nv_do_nic_poll(unsigned long data)
@@ -2929,14 +2952,17 @@
writel(NVREG_IRQSTAT_MASK, base + NvRegIrqStatus);
pci_push(base);
- if (nv_request_irq(dev)) {
- goto out_drain;
- }
-
- /* ask for interrupts */
- nv_enable_hw_interrupts(dev, np->irqmask);
-
- spin_lock_irq(&np->lock);
+ if (!np->ecdev) {
+ if (nv_request_irq(dev)) {
+ goto out_drain;
+ }
+
+ /* ask for interrupts */
+ nv_enable_hw_interrupts(dev, np->irqmask);
+
+ spin_lock_irq(&np->lock);
+ }
+
writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA);
writel(0, base + NvRegMulticastAddrB);
writel(0, base + NvRegMulticastMaskA);
@@ -2957,16 +2983,22 @@
ret = nv_update_linkspeed(dev);
nv_start_rx(dev);
nv_start_tx(dev);
- netif_start_queue(dev);
- if (ret) {
- netif_carrier_on(dev);
- } else {
- printk("%s: no link during initialization.\n", dev->name);
- netif_carrier_off(dev);
- }
- if (oom)
- mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
- spin_unlock_irq(&np->lock);
+
+ if (np->ecdev) {
+ ecdev_link_state(np->ecdev, ret);
+ }
+ else {
+ netif_start_queue(dev);
+ if (ret) {
+ netif_carrier_on(dev);
+ } else {
+ printk("%s: no link during initialization.\n", dev->name);
+ netif_carrier_off(dev);
+ }
+ if (oom)
+ mod_timer(&np->oom_kick, jiffies + OOM_REFILL);
+ spin_unlock_irq(&np->lock);
+ }
return 0;
out_drain:
@@ -2979,29 +3011,35 @@
struct fe_priv *np = netdev_priv(dev);
u8 __iomem *base;
- spin_lock_irq(&np->lock);
- np->in_shutdown = 1;
- spin_unlock_irq(&np->lock);
- synchronize_irq(dev->irq);
-
- del_timer_sync(&np->oom_kick);
- del_timer_sync(&np->nic_poll);
-
- netif_stop_queue(dev);
- spin_lock_irq(&np->lock);
+ if (!np->ecdev) {
+ spin_lock_irq(&np->lock);
+ np->in_shutdown = 1;
+ spin_unlock_irq(&np->lock);
+ synchronize_irq(dev->irq);
+
+ del_timer_sync(&np->oom_kick);
+ del_timer_sync(&np->nic_poll);
+
+ netif_stop_queue(dev);
+ spin_lock_irq(&np->lock);
+ }
+
nv_stop_tx(dev);
nv_stop_rx(dev);
nv_txrx_reset(dev);
- /* disable interrupts on the nic or we will lock up */
- base = get_hwbase(dev);
- nv_disable_hw_interrupts(dev, np->irqmask);
- pci_push(base);
- dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name);
-
- spin_unlock_irq(&np->lock);
-
- nv_free_irq(dev);
+ base = get_hwbase(dev);
+
+ if (!np->ecdev) {
+ /* disable interrupts on the nic or we will lock up */
+ nv_disable_hw_interrupts(dev, np->irqmask);
+ pci_push(base);
+ dprintk(KERN_INFO "%s: Irqmask is zero again\n", dev->name);
+
+ spin_unlock_irq(&np->lock);
+
+ nv_free_irq(dev);
+ }
drain_ring(dev);
@@ -3298,13 +3336,19 @@
np->autoneg = 1;
// offer device to EtherCAT master module
- if (ecdev_offer(dev, &np->ecdev, "forcedeth", board_idx,
- ec_poll, THIS_MODULE)) {
+ if (ecdev_offer(dev, &np->ecdev, "forcedeth", board_idx, ec_poll,
+ THIS_MODULE)) {
printk(KERN_ERR "forcedeth: Failed to offer device.\n");
goto out_freering;
}
- if (!np->ecdev) {
+ if (np->ecdev) {
+ if (ecdev_open(np->ecdev)) {
+ ecdev_withdraw(np->ecdev);
+ goto out_freering;
+ }
+ }
+ else {
err = register_netdev(dev);
if (err) {
printk(KERN_INFO "forcedeth: unable to register netdev: %d\n", err);
@@ -3436,7 +3480,9 @@
static int __init init_nic(void)
{
- printk(KERN_INFO "forcedeth.c: Reverse Engineered nForce ethernet driver. Version %s.\n", FORCEDETH_VERSION);
+ printk(KERN_INFO "forcedeth: EtherCAT-capable nForce ethernet driver."
+ " Version %s, master %s.\n",
+ FORCEDETH_VERSION, EC_MASTER_VERSION);
return pci_module_init(&driver);
}
@@ -3456,8 +3502,8 @@
module_param(disable_msix, int, 0);
MODULE_PARM_DESC(disable_msix, "Disable MSIX interrupts by setting to 1.");
-MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
-MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
+MODULE_AUTHOR("Dipl.-Ing. (FH) Florian Pose <fp@igh-essen.com>");
+MODULE_DESCRIPTION("EtherCAT-capable nForce ethernet driver");
MODULE_LICENSE("GPL");
//MODULE_DEVICE_TABLE(pci, pci_tbl); // prevent auto-loading