net/bnxt: handle fatal event from FW
authorKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Wed, 2 Oct 2019 01:23:25 +0000 (18:23 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 8 Oct 2019 10:14:30 +0000 (12:14 +0200)
When firmware hit some unrecoverable error conditions, firmware initiate
the recovery by sending an async event EVENT_CMPL_EVENT_ID_RESET_NOTIFY
with data1 set to RESET_NOTIFY_EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL
to all host drivers and will reset the chip.

The recovery procedure is same sequence as the one for hot FW upgrade.

Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
drivers/net/bnxt/bnxt_cpr.c
drivers/net/bnxt/bnxt_cpr.h
drivers/net/bnxt/bnxt_ethdev.c

index 1a23649..3afb990 100644 (file)
@@ -21,6 +21,7 @@ void bnxt_handle_async_event(struct bnxt *bp,
        struct hwrm_async_event_cmpl *async_cmp =
                                (struct hwrm_async_event_cmpl *)cmp;
        uint16_t event_id = rte_le_to_cpu_16(async_cmp->event_id);
+       uint32_t event_data;
 
        /* TODO: HWRM async events are not defined yet */
        /* Needs to handle: link events, error events, etc. */
@@ -42,6 +43,7 @@ void bnxt_handle_async_event(struct bnxt *bp,
                PMD_DRV_LOG(INFO, "Port conn async event\n");
                break;
        case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY:
+               event_data = rte_le_to_cpu_32(async_cmp->event_data1);
                /* timestamp_lo/hi values are in units of 100ms */
                bp->fw_reset_max_msecs = async_cmp->timestamp_hi ?
                        rte_le_to_cpu_16(async_cmp->timestamp_hi) * 100 :
@@ -49,8 +51,15 @@ void bnxt_handle_async_event(struct bnxt *bp,
                bp->fw_reset_min_msecs = async_cmp->timestamp_lo ?
                        async_cmp->timestamp_lo * 100 :
                        BNXT_MIN_FW_READY_TIMEOUT;
-               PMD_DRV_LOG(INFO,
-                           "Firmware non-fatal reset event received\n");
+               if ((event_data & EVENT_DATA1_REASON_CODE_MASK) ==
+                   EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL) {
+                       PMD_DRV_LOG(INFO,
+                                   "Firmware fatal reset event received\n");
+                       bp->flags |= BNXT_FLAG_FATAL_ERROR;
+               } else {
+                       PMD_DRV_LOG(INFO,
+                                   "Firmware non-fatal reset event received\n");
+               }
 
                bp->flags |= BNXT_FLAG_FW_RESET;
                rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume,
index f48293b..b61bafa 100644 (file)
@@ -108,4 +108,9 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmp);
 int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp);
 void bnxt_dev_reset_and_resume(void *arg);
 
+#define EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL     \
+       HWRM_ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL
+#define EVENT_DATA1_REASON_CODE_MASK                   \
+       HWRM_ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_MASK
+
 #endif
index 1bb84ea..768b6cd 100644 (file)
@@ -3592,6 +3592,9 @@ static void bnxt_dev_recover(void *arg)
        int timeout = bp->fw_reset_max_msecs;
        int rc = 0;
 
+       /* Clear Error flag so that device re-init should happen */
+       bp->flags &= ~BNXT_FLAG_FATAL_ERROR;
+
        do {
                rc = bnxt_hwrm_ver_get(bp);
                if (rc == 0)