# HG changeset patch # User Florian Pose # Date 1186403589 0 # Node ID 5e0d5f04dc652d2d9021dbe33c1e16b5b878afb6 # Parent 7c7cf2d6c911065f661a3b27259ab1e0219b9f9e Merged e1000 changes from 2.6.13 to 2.6.18 (not tested). diff -r 7c7cf2d6c911 -r 5e0d5f04dc65 devices/e1000/e1000-2.6.18-ethercat.h --- a/devices/e1000/e1000-2.6.18-ethercat.h Mon Aug 06 11:51:52 2007 +0000 +++ b/devices/e1000/e1000-2.6.18-ethercat.h Mon Aug 06 12:33:09 2007 +0000 @@ -347,6 +347,7 @@ unsigned long flags; ec_device_t *ecdev; + unsigned long ec_watchdog_jiffies; }; enum e1000_state_t { diff -r 7c7cf2d6c911 -r 5e0d5f04dc65 devices/e1000/e1000_main-2.6.18-ethercat.c --- a/devices/e1000/e1000_main-2.6.18-ethercat.c Mon Aug 06 11:51:52 2007 +0000 +++ b/devices/e1000/e1000_main-2.6.18-ethercat.c Mon Aug 06 12:33:09 2007 +0000 @@ -315,6 +315,8 @@ static void e1000_irq_disable(struct e1000_adapter *adapter) { + if (adapter->ecdev) + return; atomic_inc(&adapter->irq_sem); E1000_WRITE_REG(&adapter->hw, IMC, ~0); E1000_WRITE_FLUSH(&adapter->hw); @@ -329,7 +331,9 @@ static void e1000_irq_enable(struct e1000_adapter *adapter) { - if (!adapter->ecdev && likely(atomic_dec_and_test(&adapter->irq_sem))) { + if (adapter->ecdev) + return; + if (likely(atomic_dec_and_test(&adapter->irq_sem))) { E1000_WRITE_REG(&adapter->hw, IMS, IMS_ENABLE_MASK); E1000_WRITE_FLUSH(&adapter->hw); } @@ -467,12 +471,14 @@ adapter->tx_queue_len = netdev->tx_queue_len; - mod_timer(&adapter->watchdog_timer, jiffies); + if (!adapter->ecdev) { + mod_timer(&adapter->watchdog_timer, jiffies); #ifdef CONFIG_E1000_NAPI - if (!adapter->ecdev) netif_poll_enable(netdev); + netif_poll_enable(netdev); #endif - e1000_irq_enable(adapter); + e1000_irq_enable(adapter); + } return 0; } @@ -529,16 +535,18 @@ { struct net_device *netdev = adapter->netdev; - e1000_irq_disable(adapter); - - del_timer_sync(&adapter->tx_fifo_stall_timer); - del_timer_sync(&adapter->watchdog_timer); - del_timer_sync(&adapter->phy_info_timer); + if (!adapter->ecdev) { + e1000_irq_disable(adapter); + + del_timer_sync(&adapter->tx_fifo_stall_timer); + del_timer_sync(&adapter->watchdog_timer); + del_timer_sync(&adapter->phy_info_timer); #ifdef CONFIG_E1000_NAPI - if (!adapter->ecdev) netif_poll_disable(netdev); + netif_poll_disable(netdev); #endif - netdev->tx_queue_len = adapter->tx_queue_len; + netdev->tx_queue_len = adapter->tx_queue_len; + } adapter->link_speed = 0; adapter->link_duplex = 0; if (!adapter->ecdev) { @@ -1944,6 +1952,9 @@ e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, struct e1000_buffer *buffer_info) { + if (adapter->ecdev) + return; + if (buffer_info->dma) { pci_unmap_page(adapter->pdev, buffer_info->dma, @@ -2461,8 +2472,8 @@ } else { netif_carrier_on(netdev); netif_wake_queue(netdev); + mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); } - mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); adapter->smartspeed = 0; } } else { @@ -2476,8 +2487,8 @@ } else { netif_carrier_off(netdev); netif_stop_queue(netdev); + mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); } - mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); /* 80003ES2LAN workaround-- * For packet buffer work-around on link down event; @@ -2507,8 +2518,7 @@ e1000_update_adaptive(&adapter->hw); - if ((adapter->ecdev && !ecdev_get_link(adapter->ecdev)) - || (!adapter->ecdev && !netif_carrier_ok(netdev))) { + if (!adapter->ecdev && !netif_carrier_ok(netdev)) { if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) { /* We've lost link, so the controller stops DMA, * but we've got queued Tx work that's never going @@ -2536,7 +2546,7 @@ E1000_WRITE_REG(&adapter->hw, ICS, E1000_ICS_RXDMT0); /* Force detection of hung controller every watchdog period */ - adapter->detect_tx_hung = TRUE; + if (!adapter->ecdev) adapter->detect_tx_hung = TRUE; /* With 82571 controllers, LAA may be overwritten due to controller * reset from the other port. Set the appropriate LAA in RAR[0] */ @@ -2544,7 +2554,8 @@ e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0); /* Reset the timer */ - mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); + if (!adapter->ecdev) + mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ); } #define E1000_TX_FLAGS_CSUM 0x00000001 @@ -3031,11 +3042,11 @@ if (unlikely(adapter->hw.mac_type == e1000_82547)) { if (unlikely(e1000_82547_fifo_workaround(adapter, skb))) { - if (!adapter->ecdev) + if (!adapter->ecdev) { netif_stop_queue(netdev); - mod_timer(&adapter->tx_fifo_stall_timer, jiffies); - if (!adapter->ecdev) + mod_timer(&adapter->tx_fifo_stall_timer, jiffies); spin_unlock_irqrestore(&tx_ring->tx_lock, flags); + } return NETDEV_TX_BUSY; } } @@ -3388,9 +3399,16 @@ spin_unlock_irqrestore(&adapter->stats_lock, flags); } -void ec_poll(struct net_device *dev) -{ - e1000_intr(0, dev, NULL); +void ec_poll(struct net_device *netdev) +{ + struct e1000_adapter *adapter = netdev_priv(netdev); + + if (jiffies - adapter->ec_watchdog_jiffies >= 2 * HZ) { + e1000_watchdog_task(adapter); + adapter->ec_watchdog_jiffies = jiffies; + } + + e1000_intr(0, netdev, NULL); } /** @@ -3426,16 +3444,15 @@ return IRQ_NONE; /* Not our interrupt */ } - if (unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { + if (!adapter->ecdev && unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { hw->get_link_status = 1; /* 80003ES2LAN workaround-- * For packet buffer work-around on link down event; * disable receives here in the ISR and * reset adapter in watchdog */ - if (((adapter->ecdev && ecdev_get_link(adapter->ecdev)) - || (!adapter->ecdev && netif_carrier_ok(netdev))) && - (adapter->hw.mac_type == e1000_80003es2lan)) { + if (netif_carrier_ok(netdev) && + (adapter->hw.mac_type == e1000_80003es2lan)) { /* disable receives */ rctl = E1000_READ_REG(hw, RCTL); E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN); @@ -3444,17 +3461,18 @@ } #ifdef CONFIG_E1000_NAPI - if (unlikely(hw->mac_type < e1000_82571)) { - atomic_inc(&adapter->irq_sem); - E1000_WRITE_REG(hw, IMC, ~0); - E1000_WRITE_FLUSH(hw); - } - if (!adapter->ecdev) { + if (!adapter->ecdev) { + if (unlikely(hw->mac_type < e1000_82571)) { + atomic_inc(&adapter->irq_sem); + E1000_WRITE_REG(hw, IMC, ~0); + E1000_WRITE_FLUSH(hw); + } + if (likely(netif_rx_schedule_prep(netdev))) __netif_rx_schedule(netdev); else e1000_irq_enable(adapter); - } + } #else /* Writing IMC and IMS is needed for 82547. * Due to Hub Link bus being occupied, an interrupt @@ -3466,7 +3484,8 @@ * in dead lock. Writing IMC forces 82547 into * de-assertion state. */ - if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) { + if (!adapter->ecdev && + (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)) { atomic_inc(&adapter->irq_sem); E1000_WRITE_REG(hw, IMC, ~0); } @@ -3476,7 +3495,8 @@ !e1000_clean_tx_irq(adapter, adapter->tx_ring))) break; - if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) + if (adapter->ecdev && + (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)) e1000_irq_enable(adapter); #endif @@ -3581,15 +3601,15 @@ #define TX_WAKE_THRESHOLD 32 if (unlikely(!adapter->ecdev && cleaned && netif_queue_stopped(netdev) && - netif_carrier_ok(netdev))) { + netif_carrier_ok(netdev))) { spin_lock(&tx_ring->tx_lock); if (netif_queue_stopped(netdev) && - (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) + (E1000_DESC_UNUSED(tx_ring) >= TX_WAKE_THRESHOLD)) netif_wake_queue(netdev); spin_unlock(&tx_ring->tx_lock); } - if (adapter->detect_tx_hung) { + if(!adapter->ecdev && adapter->detect_tx_hung) { /* Detect a transmit hang in hardware, this serializes the * check with the clearing of time_stamp and movement of i */ adapter->detect_tx_hung = FALSE; @@ -3611,17 +3631,17 @@ " next_to_watch <%x>\n" " jiffies <%lx>\n" " next_to_watch.status <%x>\n", - (unsigned long)((tx_ring - adapter->tx_ring) / - sizeof(struct e1000_tx_ring)), - readl(adapter->hw.hw_addr + tx_ring->tdh), - readl(adapter->hw.hw_addr + tx_ring->tdt), - tx_ring->next_to_use, - tx_ring->next_to_clean, - tx_ring->buffer_info[eop].time_stamp, - eop, - jiffies, - eop_desc->upper.fields.status); - if (!adapter->ecdev) netif_stop_queue(netdev); + (unsigned long)((tx_ring - adapter->tx_ring) / + sizeof(struct e1000_tx_ring)), + readl(adapter->hw.hw_addr + tx_ring->tdh), + readl(adapter->hw.hw_addr + tx_ring->tdt), + tx_ring->next_to_use, + tx_ring->next_to_clean, + tx_ring->buffer_info[eop].time_stamp, + eop, + jiffies, + eop_desc->upper.fields.status); + netif_stop_queue(netdev); } } return cleaned; @@ -3752,13 +3772,13 @@ if (!adapter->ecdev && unlikely(rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) { last_byte = *(skb->data + length - 1); if (TBI_ACCEPT(&adapter->hw, status, - rx_desc->errors, length, last_byte)) { + rx_desc->errors, length, last_byte)) { spin_lock_irqsave(&adapter->stats_lock, flags); e1000_tbi_adjust_stats(&adapter->hw, - &adapter->stats, - length, skb->data); + &adapter->stats, + length, skb->data); spin_unlock_irqrestore(&adapter->stats_lock, - flags); + flags); length--; } else { /* recycle */ @@ -3773,13 +3793,13 @@ #define E1000_CB_LENGTH 256 if (!adapter->ecdev && length < E1000_CB_LENGTH) { struct sk_buff *new_skb = - netdev_alloc_skb(netdev, length + NET_IP_ALIGN); + netdev_alloc_skb(netdev, length + NET_IP_ALIGN); if (new_skb) { skb_reserve(new_skb, NET_IP_ALIGN); new_skb->dev = netdev; memcpy(new_skb->data - NET_IP_ALIGN, - skb->data - NET_IP_ALIGN, - length + NET_IP_ALIGN); + skb->data - NET_IP_ALIGN, + length + NET_IP_ALIGN); /* save the skb in buffer_info as good */ buffer_info->skb = skb; skb = new_skb; @@ -3798,6 +3818,16 @@ if (adapter->ecdev) { ecdev_receive(adapter->ecdev, skb->data, length); + skb_trim(skb, 0); + + if(unlikely((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i)) { + /* Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). */ + wmb(); + E1000_WRITE_REG(&adapter->hw, RDT, i); + } } else { skb->protocol = eth_type_trans(skb, netdev); #ifdef CONFIG_E1000_NAPI @@ -3982,6 +4012,20 @@ adapter->rx_hdr_split++; if (adapter->ecdev) { ecdev_receive(adapter->ecdev, skb->data, length); + skb_trim(skb, 0); + + if(unlikely((i & ~(E1000_RX_BUFFER_WRITE - 1)) == i)) { + /* Force memory writes to complete before letting h/w + * know there are new descriptors to fetch. (Only + * applicable for weak-ordered memory model archs, + * such as IA-64). */ + wmb(); + /* Hardware increments by 16 bytes, but packet split + * descriptors are 32 bytes...so we increment tail + * twice as much. + */ + E1000_WRITE_REG(&adapter->hw, RDT, i<<1); + } } else { skb->protocol = eth_type_trans(skb, netdev); #ifdef CONFIG_E1000_NAPI @@ -4344,7 +4388,7 @@ data->phy_id = adapter->hw.phy_addr; break; case SIOCGMIIREG: - if (!capable(CAP_NET_ADMIN)) + if(adapter->ecdev || !capable(CAP_NET_ADMIN)) return -EPERM; spin_lock_irqsave(&adapter->stats_lock, flags); if (e1000_read_phy_reg(&adapter->hw, data->reg_num & 0x1F, @@ -4355,7 +4399,7 @@ spin_unlock_irqrestore(&adapter->stats_lock, flags); break; case SIOCSMIIREG: - if (!capable(CAP_NET_ADMIN)) + if(adapter->ecdev || !capable(CAP_NET_ADMIN)) return -EPERM; if (data->reg_num & ~(0x1F)) return -EFAULT;