be2net: Fix UE detection logic for BE3
authorSuresh Reddy <suresh.reddy@broadcom.com>
Thu, 25 May 2017 02:24:38 +0000 (22:24 -0400)
committerDavid S. Miller <davem@davemloft.net>
Thu, 25 May 2017 18:44:49 +0000 (14:44 -0400)
On certain platforms BE3 chips may indicate spurious UEs (unrecoverable
error). Because of the UE detection logic was disabled in the driver
for BE3 chips. Because of this, even in cases of a real UE,
a failover will not occur. This patch re-enables UE detection on BE3
and if a UE is detected, reads the POST register. If the POST register,
reports either a FAT_LOG_STATE or a ARMFW_UE, then it means that a valid
UE occurred in the chip.

Signed-off-by: Suresh Reddy <suresh.reddy@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/emulex/benet/be_hw.h
drivers/net/ethernet/emulex/benet/be_main.c

index 36e4232ed6b892ad45d83caa2e84e55e87fa505e..c967f45705d996acc968c396e21d6cffc2e922f7 100644 (file)
@@ -49,6 +49,9 @@
 #define POST_STAGE_BE_RESET            0x3 /* Host wants to reset chip */
 #define POST_STAGE_ARMFW_RDY           0xc000  /* FW is done with POST */
 #define POST_STAGE_RECOVERABLE_ERR     0xE000  /* Recoverable err detected */
+/* FW has detected a UE and is dumping FAT log data */
+#define POST_STAGE_FAT_LOG_START       0x0D00
+#define POST_STAGE_ARMFW_UE            0xF000  /*FW has asserted an UE*/
 
 /* Lancer SLIPORT registers */
 #define SLIPORT_STATUS_OFFSET          0x404
index f3a09ab559004b80106e957674cb0d6acbf3ea65..8000551135837ffe04b0f29bc1caab988bc5be56 100644 (file)
@@ -3241,8 +3241,9 @@ void be_detect_error(struct be_adapter *adapter)
 {
        u32 ue_lo = 0, ue_hi = 0, ue_lo_mask = 0, ue_hi_mask = 0;
        u32 sliport_status = 0, sliport_err1 = 0, sliport_err2 = 0;
-       u32 i;
        struct device *dev = &adapter->pdev->dev;
+       u16 val;
+       u32 i;
 
        if (be_check_error(adapter, BE_ERROR_HW))
                return;
@@ -3280,15 +3281,25 @@ void be_detect_error(struct be_adapter *adapter)
                ue_lo = (ue_lo & ~ue_lo_mask);
                ue_hi = (ue_hi & ~ue_hi_mask);
 
-               /* On certain platforms BE hardware can indicate spurious UEs.
-                * Allow HW to stop working completely in case of a real UE.
-                * Hence not setting the hw_error for UE detection.
-                */
-
                if (ue_lo || ue_hi) {
+                       /* On certain platforms BE3 hardware can indicate
+                        * spurious UEs. In case of a UE in the chip,
+                        * the POST register correctly reports either a
+                        * FAT_LOG_START state (FW is currently dumping
+                        * FAT log data) or a ARMFW_UE state. Check for the
+                        * above states to ascertain if the UE is valid or not.
+                        */
+                       if (BE3_chip(adapter)) {
+                               val = be_POST_stage_get(adapter);
+                               if ((val & POST_STAGE_FAT_LOG_START)
+                                    != POST_STAGE_FAT_LOG_START &&
+                                   (val & POST_STAGE_ARMFW_UE)
+                                    != POST_STAGE_ARMFW_UE)
+                                       return;
+                       }
+
                        dev_err(dev, "Error detected in the adapter");
-                       if (skyhawk_chip(adapter))
-                               be_set_error(adapter, BE_ERROR_UE);
+                       be_set_error(adapter, BE_ERROR_UE);
 
                        for (i = 0; ue_lo; ue_lo >>= 1, i++) {
                                if (ue_lo & 1)