devices/e1000/e1000_main-2.6.13-ethercat.c
changeset 676 aa394dc1943a
parent 673 21c266c3f463
child 677 7c7cf2d6c911
--- a/devices/e1000/e1000_main-2.6.13-ethercat.c	Fri Aug 03 14:11:37 2007 +0000
+++ b/devices/e1000/e1000_main-2.6.13-ethercat.c	Mon Aug 06 11:46:41 2007 +0000
@@ -245,6 +245,8 @@
 static inline 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);
@@ -259,7 +261,9 @@
 static inline 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);
 	}
@@ -322,20 +326,22 @@
 		}
 	}
 #endif
-	if((err = request_irq(adapter->pdev->irq, &e1000_intr,
-		              SA_SHIRQ | SA_SAMPLE_RANDOM,
-		              netdev->name, netdev))) {
-		DPRINTK(PROBE, ERR,
-		    "Unable to allocate interrupt Error: %d\n", err);
-		return err;
-	}
-
-	mod_timer(&adapter->watchdog_timer, jiffies);
+    if (!adapter->ecdev) {
+        if((err = request_irq(adapter->pdev->irq, &e1000_intr,
+                        SA_SHIRQ | SA_SAMPLE_RANDOM,
+                        netdev->name, netdev))) {
+            DPRINTK(PROBE, ERR,
+                    "Unable to allocate interrupt Error: %d\n", err);
+            return err;
+        }
+
+        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;
 }
@@ -345,20 +351,24 @@
 {
 	struct net_device *netdev = adapter->netdev;
 
-	e1000_irq_disable(adapter);
-	free_irq(adapter->pdev->irq, netdev);
+    if (!adapter->ecdev) {
+        e1000_irq_disable(adapter);
+        free_irq(adapter->pdev->irq, netdev);
+    }
 #ifdef CONFIG_PCI_MSI
 	if(adapter->hw.mac_type > e1000_82547_rev_2 &&
 	   adapter->have_msi == TRUE)
 		pci_disable_msi(adapter->pdev);
 #endif
-	del_timer_sync(&adapter->tx_fifo_stall_timer);
-	del_timer_sync(&adapter->watchdog_timer);
-	del_timer_sync(&adapter->phy_info_timer);
+    if (!adapter->ecdev) {
+        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
+    }
 	adapter->link_speed = 0;
 	adapter->link_duplex = 0;
 	if (!adapter->ecdev) {
@@ -1422,6 +1432,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,
@@ -1653,12 +1666,13 @@
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	struct dev_mc_list *mc_ptr;
-	unsigned long flags;
+	unsigned long flags = 0;
 	uint32_t rctl;
 	uint32_t hash_value;
 	int i;
 
-	spin_lock_irqsave(&adapter->tx_lock, flags);
+    if (!adapter->ecdev)
+        spin_lock_irqsave(&adapter->tx_lock, flags);
 
 	/* Check for Promiscuous and All Multicast modes */
 
@@ -1711,7 +1725,8 @@
 	if(hw->mac_type == e1000_82542_rev2_0)
 		e1000_leave_82542_rst(adapter);
 
-	spin_unlock_irqrestore(&adapter->tx_lock, flags);
+    if (!adapter->ecdev)
+        spin_unlock_irqrestore(&adapter->tx_lock, flags);
 }
 
 /* Need to wait a few seconds after link up to get diagnostic information from
@@ -1816,8 +1831,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 {
@@ -1831,8 +1846,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);
 		}
 
 		e1000_smartspeed(adapter);
@@ -1852,8 +1867,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
@@ -1880,10 +1894,11 @@
 	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;
 
 	/* 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
@@ -2298,14 +2313,16 @@
 	if(adapter->pcix_82544)
 		count += nr_frags;
 
- 	local_irq_save(flags); 
- 	if (!spin_trylock(&adapter->tx_lock)) { 
- 		/* Collision - tell upper layer to requeue */ 
- 		local_irq_restore(flags); 
- 		return NETDEV_TX_LOCKED; 
- 	} 
-	if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
-		e1000_transfer_dhcp_info(adapter, skb);
+	if (!adapter->ecdev) {
+		local_irq_save(flags); 
+		if (!spin_trylock(&adapter->tx_lock)) { 
+			/* Collision - tell upper layer to requeue */ 
+			local_irq_restore(flags); 
+			return NETDEV_TX_LOCKED; 
+		} 
+		if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
+			e1000_transfer_dhcp_info(adapter, skb);
+	}
 
 
 	/* need: count + 2 desc gap to keep tail from touching
@@ -2320,11 +2337,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(&adapter->tx_lock, flags);
+            }
 			return NETDEV_TX_BUSY;
 		}
 	}
@@ -2624,9 +2641,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);
 }
 
 /**
@@ -2652,11 +2676,12 @@
 
 	if(unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) {
 		hw->get_link_status = 1;
-		mod_timer(&adapter->watchdog_timer, jiffies);
+		if (!adapter->ecdev)
+            mod_timer(&adapter->watchdog_timer, jiffies);
 	}
 
 #ifdef CONFIG_E1000_NAPI
-	if(likely(netif_rx_schedule_prep(netdev))) {
+	if(!adapter->ecdev && likely(netif_rx_schedule_prep(netdev))) {
 
 		/* Disable interrupts and register for poll. The flush 
 		  of the posted write is intentionally left out.
@@ -2664,8 +2689,7 @@
 
 		atomic_inc(&adapter->irq_sem);
 		E1000_WRITE_REG(hw, IMC, ~0);
-        if (!adapter->ecdev)
-            __netif_rx_schedule(netdev);
+		__netif_rx_schedule(netdev);
 	}
 #else
 	/* Writing IMC and IMS is needed for 82547.
@@ -2678,7 +2702,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);
 	}
@@ -2801,7 +2826,7 @@
 		spin_unlock(&adapter->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 */
@@ -2835,7 +2860,7 @@
 				eop,
 				jiffies,
 				eop_desc->upper.fields.status);
-			if (!adapter->ecdev) netif_stop_queue(netdev);
+			netif_stop_queue(netdev);
 		}
 	}
 #ifdef NETIF_F_TSO
@@ -2980,6 +3005,16 @@
 				  rx_desc->csum, skb);
 		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
@@ -3006,13 +3041,17 @@
 
 next_desc:
 		rx_desc->status = 0;
-		buffer_info->skb = NULL;
+		if (!adapter->ecdev) buffer_info->skb = NULL;
 		if(unlikely(++i == rx_ring->count)) i = 0;
 
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 	}
 	rx_ring->next_to_clean = i;
-	adapter->alloc_rx_buf(adapter);
+	if (adapter->ecdev) {
+		rx_ring->next_to_use = i;
+	} else {
+		adapter->alloc_rx_buf(adapter);
+	}
 
 	return cleaned;
 }
@@ -3113,6 +3152,20 @@
 #endif
 		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
@@ -3144,7 +3197,11 @@
 		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
 	}
 	rx_ring->next_to_clean = i;
-	adapter->alloc_rx_buf(adapter);
+	if (adapter->ecdev) { 
+		rx_ring->next_to_use = i;
+	} else {
+		adapter->alloc_rx_buf(adapter);
+	}
 
 	return cleaned;
 }
@@ -3440,7 +3497,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,
@@ -3451,7 +3508,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;