e1000 also supporting PCI MSI interrupts.
authorFlorian Pose <fp@igh-essen.com>
Fri, 10 Aug 2007 08:58:39 +0000
changeset 694 54a169382e28
parent 693 e341f1788608
child 695 661ad8bd5ea1
e1000 also supporting PCI MSI interrupts.
devices/e1000/e1000_main-2.6.20-ethercat.c
--- a/devices/e1000/e1000_main-2.6.20-ethercat.c	Thu Aug 09 15:45:56 2007 +0000
+++ b/devices/e1000/e1000_main-2.6.20-ethercat.c	Fri Aug 10 08:58:39 2007 +0000
@@ -3837,7 +3837,11 @@
         adapter->ec_watchdog_jiffies = jiffies;
     }
 
+#ifdef CONFIG_PCI_MSI
+	e1000_intr_msi(0, netdev);
+#else
     e1000_intr(0, netdev);
+#endif
 }
 
 #ifdef CONFIG_PCI_MSI
@@ -3853,77 +3857,91 @@
 	struct net_device *netdev = data;
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
-#ifndef CONFIG_E1000_NAPI
 	int i;
-#endif
-
-	/* this code avoids the read of ICR but has to get 1000 interrupts
-	 * at every link change event before it will notice the change */
-	if (++adapter->detect_link >= 1000) {
-		uint32_t icr = E1000_READ_REG(hw, ICR);
 #ifdef CONFIG_E1000_NAPI
-		/* read ICR disables interrupts using IAM, so keep up with our
-		 * enable/disable accounting */
-		atomic_inc(&adapter->irq_sem);
-#endif
-		adapter->detect_link = 0;
-		if ((icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) &&
-		    (icr & E1000_ICR_INT_ASSERTED)) {
-			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 (netif_carrier_ok(netdev) &&
-			    (adapter->hw.mac_type == e1000_80003es2lan)) {
-				/* disable receives */
-				uint32_t rctl = E1000_READ_REG(hw, RCTL);
-				E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+	int ec_work_done = 0;
+#endif
+
+	if (adapter->ecdev) {
+		for (i = 0; i < E1000_MAX_INTR; i++)
+#ifdef CONFIG_E1000_NAPI
+			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
+                            &ec_work_done, 100) &
+						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+#else
+			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+#endif
+				break;
+	} else {
+		/* this code avoids the read of ICR but has to get 1000 interrupts
+		 * at every link change event before it will notice the change */
+		if (++adapter->detect_link >= 1000) {
+			uint32_t icr = E1000_READ_REG(hw, ICR);
+#ifdef CONFIG_E1000_NAPI
+			/* read ICR disables interrupts using IAM, so keep up with our
+			 * enable/disable accounting */
+			atomic_inc(&adapter->irq_sem);
+#endif
+			adapter->detect_link = 0;
+			if ((icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) &&
+					(icr & E1000_ICR_INT_ASSERTED)) {
+				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 (netif_carrier_ok(netdev) &&
+						(adapter->hw.mac_type == e1000_80003es2lan)) {
+					/* disable receives */
+					uint32_t rctl = E1000_READ_REG(hw, RCTL);
+					E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
+				}
+				/* guard against interrupt when we're going down */
+				if (!test_bit(__E1000_DOWN, &adapter->flags))
+					mod_timer(&adapter->watchdog_timer,
+							jiffies + 1);
 			}
-			/* guard against interrupt when we're going down */
-			if (!test_bit(__E1000_DOWN, &adapter->flags))
-				mod_timer(&adapter->watchdog_timer,
-				          jiffies + 1);
-		}
-	} else {
-		E1000_WRITE_REG(hw, ICR, (0xffffffff & ~(E1000_ICR_RXSEQ |
-		                                         E1000_ICR_LSC)));
-		/* bummer we have to flush here, but things break otherwise as
-		 * some event appears to be lost or delayed and throughput
-		 * drops.  In almost all tests this flush is un-necessary */
-		E1000_WRITE_FLUSH(hw);
+		} else {
+			E1000_WRITE_REG(hw, ICR, (0xffffffff & ~(E1000_ICR_RXSEQ |
+							E1000_ICR_LSC)));
+			/* bummer we have to flush here, but things break otherwise as
+			 * some event appears to be lost or delayed and throughput
+			 * drops.  In almost all tests this flush is un-necessary */
+			E1000_WRITE_FLUSH(hw);
 #ifdef CONFIG_E1000_NAPI
-		/* Interrupt Auto-Mask (IAM)...upon writing ICR, interrupts are
-		 * masked.  No need for the IMC write, but it does mean we
-		 * should account for it ASAP. */
-		atomic_inc(&adapter->irq_sem);
-#endif
-	}
+			/* Interrupt Auto-Mask (IAM)...upon writing ICR, interrupts are
+			 * masked.  No need for the IMC write, but it does mean we
+			 * should account for it ASAP. */
+			atomic_inc(&adapter->irq_sem);
+#endif
+		}
 
 #ifdef CONFIG_E1000_NAPI
-	if (likely(netif_rx_schedule_prep(netdev))) {
+		if (likely(netif_rx_schedule_prep(netdev))) {
+			adapter->total_tx_bytes = 0;
+			adapter->total_tx_packets = 0;
+			adapter->total_rx_bytes = 0;
+			adapter->total_rx_packets = 0;
+			__netif_rx_schedule(netdev);
+		} else
+			e1000_irq_enable(adapter);
+#else
 		adapter->total_tx_bytes = 0;
+		adapter->total_rx_bytes = 0;
 		adapter->total_tx_packets = 0;
-		adapter->total_rx_bytes = 0;
 		adapter->total_rx_packets = 0;
-		__netif_rx_schedule(netdev);
-	} else
-		e1000_irq_enable(adapter);
-#else
-	adapter->total_tx_bytes = 0;
-	adapter->total_rx_bytes = 0;
-	adapter->total_tx_packets = 0;
-	adapter->total_rx_packets = 0;
-
-	for (i = 0; i < E1000_MAX_INTR; i++)
-		if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
-		   !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
-			break;
-
-	if (likely(adapter->itr_setting & 3))
-		e1000_set_itr(adapter);
-#endif
+
+		for (i = 0; i < E1000_MAX_INTR; i++)
+			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+				break;
+
+		if (likely(adapter->itr_setting & 3))
+			e1000_set_itr(adapter);
+#endif
+	}
 
 	return IRQ_HANDLED;
 }
@@ -3942,8 +3960,9 @@
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t rctl, icr = E1000_READ_REG(hw, ICR);
-#ifndef CONFIG_E1000_NAPI
 	int i;
+#ifdef CONFIG_E1000_NAPI
+	int ec_work_done = 0;
 #endif
 	if (unlikely(!icr))
 		return IRQ_NONE;  /* Not our interrupt */
@@ -3981,8 +4000,19 @@
 			mod_timer(&adapter->watchdog_timer, jiffies + 1);
 	}
 
+	if (adapter->ecdev) {
+		for (i = 0; i < E1000_MAX_INTR; i++)
 #ifdef CONFIG_E1000_NAPI
-	if (!adapter->ecdev) {
+			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring,
+                            &ec_work_done, 100) &
+						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+#else
+			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+#endif
+				break;
+	} else {
+#ifdef CONFIG_E1000_NAPI
 		if (unlikely(hw->mac_type < e1000_82571)) {
 			/* disable interrupts, without the synchronize_irq bit */
 			atomic_inc(&adapter->irq_sem);
@@ -3999,43 +4029,40 @@
 			/* this really should not happen! if it does it is basically a
 			 * bug, but not a hard error, so enable ints and continue */
 			e1000_irq_enable(adapter);
-	}
 #else
-	/* Writing IMC and IMS is needed for 82547.
-	 * Due to Hub Link bus being occupied, an interrupt
-	 * de-assertion message is not able to be sent.
-	 * When an interrupt assertion message is generated later,
-	 * two messages are re-ordered and sent out.
-	 * That causes APIC to think 82547 is in de-assertion
-	 * state, while 82547 is in assertion state, resulting
-	 * in dead lock. Writing IMC forces 82547 into
-	 * de-assertion state.
-	 */
-	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);
-	}
-
-	adapter->total_tx_bytes = 0;
-	adapter->total_rx_bytes = 0;
-	adapter->total_tx_packets = 0;
-	adapter->total_rx_packets = 0;
-
-	for (i = 0; i < E1000_MAX_INTR; i++)
-		if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
-		   !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
-			break;
-
-    if (!adapter->ecdev) {
+		/* Writing IMC and IMS is needed for 82547.
+		 * Due to Hub Link bus being occupied, an interrupt
+		 * de-assertion message is not able to be sent.
+		 * When an interrupt assertion message is generated later,
+		 * two messages are re-ordered and sent out.
+		 * That causes APIC to think 82547 is in de-assertion
+		 * state, while 82547 is in assertion state, resulting
+		 * in dead lock. Writing IMC forces 82547 into
+		 * de-assertion state.
+		 */
+		if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2) {
+			atomic_inc(&adapter->irq_sem);
+			E1000_WRITE_REG(hw, IMC, ~0);
+		}
+
+		adapter->total_tx_bytes = 0;
+		adapter->total_rx_bytes = 0;
+		adapter->total_tx_packets = 0;
+		adapter->total_rx_packets = 0;
+
+		for (i = 0; i < E1000_MAX_INTR; i++)
+			if (unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+						!e1000_clean_tx_irq(adapter, adapter->tx_ring)))
+				break;
+
 		if (likely(adapter->itr_setting & 3))
 			e1000_set_itr(adapter);
 
 		if (hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
 			e1000_irq_enable(adapter);
-	}
-
-#endif
+
+#endif
+	}
 	return IRQ_HANDLED;
 }