e1000 fixes (NAPI)

From: Robert Olsson (Robert.Olsson@data.slu.se)
Date: Wed Nov 20 2002 - 14:01:16 EST


Two fixes the NAPI branch of e1000.

1) e1000_irq_disable was used to disable irqs which called synchronize_irq
   which in turn caused a solid hang on SMP systems.

2) Interrupt acking patch previously sent by DaveM.

Cheers.
                                                --ro

--- linux/drivers/net/e1000.vanilla/e1000.h 2002-11-13 12:54:49.000000000 +0100
+++ linux/drivers/net/e1000/e1000.h 2002-11-20 15:00:14.000000000 +0100
@@ -181,6 +181,10 @@
         uint32_t tx_abs_int_delay;
         int max_data_per_txd;
 
+#ifdef CONFIG_E1000_NAPI
+ uint32_t icr_pending;
+#endif
+
         /* RX */
         struct e1000_desc_ring rx_ring;
         uint64_t hw_csum_err;
--- linux/drivers/net/e1000.vanilla/e1000_main.c 2002-11-13 12:54:49.000000000 +0100
+++ linux/drivers/net/e1000/e1000_main.c 2002-11-20 17:37:55.000000000 +0100
@@ -1896,15 +1896,29 @@
 {
         struct net_device *netdev = data;
         struct e1000_adapter *adapter = netdev->priv;
+ uint32_t icr;
+ int i = E1000_MAX_INTR;
+
         
 #ifdef CONFIG_E1000_NAPI
- if (netif_rx_schedule_prep(netdev)) {
- e1000_irq_disable(adapter);
+ icr = E1000_READ_REG(&adapter->hw, ICR);
+ if (icr && netif_rx_schedule_prep(netdev)) {
+
+ /* Disable interrupts */
+ atomic_inc(&adapter->irq_sem);
+ E1000_WRITE_REG(&adapter->hw, IMC, ~0);
+
+ /* E1000_WRITE_FLUSH(&adapter->hw);
+ * E1000_READ below syncs it --ro
+ */
+
                 __netif_rx_schedule(netdev);
+
+ adapter->icr_pending = icr;
+ while (i-- && (icr = E1000_READ_REG(&adapter->hw, ICR)) != 0)
+ adapter->icr_pending |= icr;
         }
 #else
- uint32_t icr;
- int i = E1000_MAX_INTR;
 
         while(i && (icr = E1000_READ_REG(&adapter->hw, ICR))) {
 
@@ -1930,7 +1944,15 @@
         int i = E1000_MAX_INTR;
         int hasReceived = 0;
 
- while(i && (icr = E1000_READ_REG(&adapter->hw, ICR))) {
+ while(i) {
+ if (adapter->icr_pending) {
+ icr = adapter->icr_pending;
+ adapter->icr_pending = 0;
+ } else
+ icr = E1000_READ_REG(&adapter->hw, ICR);
+ if (!icr)
+ break;
+
                 if (icr & E1000_ICR_RXT0)
                         hasReceived = 1;
  

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Sat Nov 23 2002 - 22:00:33 EST