be2net: Wait till resources are available for VF in error recovery
authorPadmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Sat, 20 Oct 2012 06:02:27 +0000 (06:02 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 22 Oct 2012 02:15:36 +0000 (22:15 -0400)
After FW error, driver should wait for NO_RESOURCE error to disappear before
proceeding with recovery.

Signed-off-by: Padmanabh Ratnakar <padmanabh.ratnakar@emulex.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be_cmds.c
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c

index 3980b5815d8d7763937db1ee4e9bbb80c6e2c9b8..9a12c4b99e26264fc6b1c9247aba5c06e338d632 100644 (file)
@@ -452,10 +452,33 @@ int lancer_wait_ready(struct be_adapter *adapter)
        return status;
 }
 
+static bool lancer_provisioning_error(struct be_adapter *adapter)
+{
+       u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
+       sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
+       if (sliport_status & SLIPORT_STATUS_ERR_MASK) {
+               sliport_err1 = ioread32(adapter->db +
+                                       SLIPORT_ERROR1_OFFSET);
+               sliport_err2 = ioread32(adapter->db +
+                                       SLIPORT_ERROR2_OFFSET);
+
+               if (sliport_err1 == SLIPORT_ERROR_NO_RESOURCE1 &&
+                   sliport_err2 == SLIPORT_ERROR_NO_RESOURCE2)
+                       return true;
+       }
+       return false;
+}
+
 int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
 {
        int status;
        u32 sliport_status, err, reset_needed;
+       bool resource_error;
+
+       resource_error = lancer_provisioning_error(adapter);
+       if (resource_error)
+               return -1;
+
        status = lancer_wait_ready(adapter);
        if (!status) {
                sliport_status = ioread32(adapter->db + SLIPORT_STATUS_OFFSET);
@@ -477,6 +500,14 @@ int lancer_test_and_set_rdy_state(struct be_adapter *adapter)
                        status = -1;
                }
        }
+       /* Stop error recovery if error is not recoverable.
+        * No resource error is temporary errors and will go away
+        * when PF provisions resources.
+        */
+       resource_error = lancer_provisioning_error(adapter);
+       if (status == -1 && !resource_error)
+               adapter->eeh_error = true;
+
        return status;
 }
 
index b755f7061dce56edf88e486662c7d0c0b100a2a8..4ccbc36874e9ee6336cc287d98b0faad8ebaa9f2 100644 (file)
@@ -59,6 +59,9 @@
 #define PHYSDEV_CONTROL_FW_RESET_MASK  0x00000002
 #define PHYSDEV_CONTROL_INP_MASK       0x40000000
 
+#define SLIPORT_ERROR_NO_RESOURCE1     0x2
+#define SLIPORT_ERROR_NO_RESOURCE2     0x9
+
 /********* Memory BAR register ************/
 #define PCICFG_MEMBAR_CTRL_INT_CTRL_OFFSET     0xfc
 /* Host Interrupt Enable, if set interrupts are enabled although "PCI Interrupt
index 41f935a2d05da3ad4c7f6bd144fee429c9b8da50..7a483fdd974ba1d548b891f76dd9df76ca694a12 100644 (file)
@@ -3837,8 +3837,9 @@ static int lancer_recover_func(struct be_adapter *adapter)
                "Adapter SLIPORT recovery succeeded\n");
        return 0;
 err:
-       dev_err(&adapter->pdev->dev,
-               "Adapter SLIPORT recovery failed\n");
+       if (adapter->eeh_error)
+               dev_err(&adapter->pdev->dev,
+                       "Adapter SLIPORT recovery failed\n");
 
        return status;
 }