diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 637ee9a0f7..f47874882b 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -390,6 +390,8 @@ struct bnxt_error_recovery_info { #define BNXT_GRCP_WINDOW_2_BASE 0x2000 #define BNXT_GRCP_WINDOW_3_BASE 0x3000 +#define BNXT_FW_STATUS_SHUTDOWN 0x100000 + #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) struct bnxt { void *bar0; @@ -421,6 +423,7 @@ struct bnxt { #define BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE (1 << 18) #define BNXT_FLAG_FW_CAP_ERROR_RECOVERY (1 << 19) #define BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED (1 << 20) +#define BNXT_FLAG_FW_CAP_ERR_RECOVER_RELOAD (1 << 21) #define BNXT_FLAG_EXT_STATS_SUPPORTED (1 << 29) #define BNXT_FLAG_NEW_RM (1 << 30) #define BNXT_FLAG_INIT_DONE (1U << 31) diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c index 38931799eb..00ca6bbd1f 100644 --- a/drivers/net/bnxt/bnxt_cpr.c +++ b/drivers/net/bnxt/bnxt_cpr.c @@ -5,6 +5,7 @@ #include #include +#include #include "bnxt.h" #include "bnxt_cpr.h" @@ -12,6 +13,40 @@ #include "bnxt_ring.h" #include "hsi_struct_def_dpdk.h" +void bnxt_wait_for_device_shutdown(struct bnxt *bp) +{ + uint32_t val, timeout; + + /* if HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERR_RECOVER_RELOAD is set + * in HWRM_FUNC_QCAPS command, wait for FW_STATUS to set + * the SHUTDOWN bit in health register + */ + if (!(bp->recovery_info && + (bp->flags & BNXT_FLAG_FW_CAP_ERR_RECOVER_RELOAD))) + return; + + /* Driver has to wait for fw_reset_max_msecs or shutdown bit which comes + * first for FW to collect crash dump. + */ + timeout = bp->fw_reset_max_msecs; + + /* Driver has to poll for shutdown bit in fw_status register + * + * 1. in case of hot fw upgrade, this bit will be set after all + * function drivers unregistered with fw. + * 2. in case of fw initiated error recovery, this bit will be + * set after fw has collected the core dump + */ + do { + val = bnxt_read_fw_status_reg(bp, BNXT_FW_STATUS_REG); + if (val & BNXT_FW_STATUS_SHUTDOWN) + return; + + rte_delay_ms(100); + timeout -= 100; + } while (timeout); +} + /* * Async event handling */ diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h index f118bda36e..c2880783f6 100644 --- a/drivers/net/bnxt/bnxt_cpr.h +++ b/drivers/net/bnxt/bnxt_cpr.h @@ -107,6 +107,7 @@ void bnxt_handle_async_event(struct bnxt *bp, struct cmpl_base *cmp); 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); +void bnxt_wait_for_device_shutdown(struct bnxt *bp); #define EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL \ HWRM_ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 40973c37b9..fbd00d1c72 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -3721,6 +3721,8 @@ void bnxt_dev_reset_and_resume(void *arg) bnxt_dev_cleanup(bp); + bnxt_wait_for_device_shutdown(bp); + rc = rte_eal_alarm_set(US_PER_MS * bp->fw_reset_min_msecs, bnxt_dev_recover, (void *)bp); if (rc) diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index e96e6cef91..7304cbf72c 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -637,6 +637,11 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) bp->flags &= ~BNXT_FLAG_FW_CAP_ERROR_RECOVERY; } + if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERR_RECOVER_RELOAD) + bp->flags |= BNXT_FLAG_FW_CAP_ERR_RECOVER_RELOAD; + else + bp->flags &= ~BNXT_FLAG_FW_CAP_ERR_RECOVER_RELOAD; + HWRM_UNLOCK(); return rc; diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h index 809ea48736..bd04fe4838 100644 --- a/drivers/net/bnxt/hsi_struct_def_dpdk.h +++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h @@ -7327,6 +7327,14 @@ struct hwrm_func_qcaps_output { */ #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED \ UINT32_C(0x1000000) + /* + * If the query is for a VF, then this flag shall be ignored. + * If this query is for a PF and this flag is set to 1, then host + * must initiate reset or reload (or fastboot) the firmware image + * upon detection of device shutdown state. + */ + #define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERR_RECOVER_RELOAD \ + UINT32_C(0x2000000) /* * This value is current MAC address configured for this * function. A value of 00-00-00-00-00-00 indicates no