atl1: enable errors and link ints when rx/tx scheduled
authorTony Zelenoff <antonz@parallels.com>
Fri, 13 Apr 2012 06:09:52 +0000 (06:09 +0000)
committerDavid S. Miller <davem@davemloft.net>
Sun, 15 Apr 2012 16:56:02 +0000 (12:56 -0400)
Signed-off-by: Tony Zelenoff <antonz@parallels.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/atheros/atlx/atl1.c
drivers/net/ethernet/atheros/atlx/atl1.h

index 93c92291da9ce00180370ff5a2ff170775dad25e..f17cecae59e57987360fa66f76c7d210c4c4e0c1 100644 (file)
@@ -2460,20 +2460,33 @@ static int atl1_rings_clean(struct napi_struct *napi, int budget)
 
        napi_complete(napi);
        /* re-enable Interrupt */
-       iowrite32(ISR_DIS_SMB | ISR_DIS_DMA, adapter->hw.hw_addr + REG_ISR);
+       if (likely(adapter->int_enabled))
+               atlx_imr_set(adapter, IMR_NORMAL_MASK);
        return work_done;
 }
 
 static inline int atl1_sched_rings_clean(struct atl1_adapter* adapter)
 {
-       if (likely(napi_schedule_prep(&adapter->napi))) {
-               __napi_schedule(&adapter->napi);
+       if (!napi_schedule_prep(&adapter->napi))
+               /* It is possible in case even the RX/TX ints are disabled via IMR
+                * register the ISR bits are set anyway (but do not produce IRQ).
+                * To handle such situation the napi functions used to check is
+                * something scheduled or not.
+                */
+               return 0;
+
+       __napi_schedule(&adapter->napi);
+
+       /*
+        * Disable RX/TX ints via IMR register if it is
+        * allowed. NAPI handler must reenable them in same
+        * way.
+        */
+       if (!adapter->int_enabled)
                return 1;
-       }
 
-       dev_printk(KERN_ERR, &adapter->pdev->dev,
-                  "rx: INTs must be disabled!");
-       return 0;
+       atlx_imr_set(adapter, IMR_NORXTX_MASK);
+       return 1;
 }
 
 /*
@@ -2538,8 +2551,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
                /* transmit or receive event */
                if (status & (ISR_CMB_TX | ISR_CMB_RX) &&
                    atl1_sched_rings_clean(adapter))
-                       /* Go away with INTs disabled */
-                       return IRQ_HANDLED;
+                       break;
 
                /* rx exception */
                if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN |
@@ -2551,7 +2563,7 @@ static irqreturn_t atl1_intr(int irq, void *data)
                                        "rx exception, ISR = 0x%x\n",
                                        status);
                        if (atl1_sched_rings_clean(adapter))
-                               return IRQ_HANDLED;
+                               break;
                }
 
                if (--max_ints < 0)
index 117a0da360b852eb00882f37d10af7e73322a86e..1cb658b2ff923eeff3f9277a7fca65f9c3d75d3d 100644 (file)
@@ -275,13 +275,17 @@ static u32 atl1_check_link(struct atl1_adapter *adapter);
 #define ISR_DIS_SMB                            0x20000000
 #define ISR_DIS_DMA                            0x40000000
 
-/* Normal Interrupt mask  */
-#define IMR_NORMAL_MASK        (\
+/* Normal Interrupt mask without RX/TX enabled */
+#define IMR_NORXTX_MASK        (\
        ISR_SMB         |\
        ISR_GPHY        |\
        ISR_PHY_LINKDOWN|\
        ISR_DMAR_TO_RST |\
-       ISR_DMAW_TO_RST |\
+       ISR_DMAW_TO_RST)
+
+/* Normal Interrupt mask  */
+#define IMR_NORMAL_MASK        (\
+       IMR_NORXTX_MASK |\
        ISR_CMB_TX      |\
        ISR_CMB_RX)