bp->fw_cap |= BNXT_FW_CAP_EXT_STATS_SUPPORTED;
        if (flags &  FUNC_QCAPS_RESP_FLAGS_ERROR_RECOVERY_CAPABLE)
                bp->fw_cap |= BNXT_FW_CAP_ERROR_RECOVERY;
+       if (flags & FUNC_QCAPS_RESP_FLAGS_ERR_RECOVER_RELOAD)
+               bp->fw_cap |= BNXT_FW_CAP_ERR_RECOVER_RELOAD;
 
        bp->tx_push_thresh = 0;
        if (flags & FUNC_QCAPS_RESP_FLAGS_PUSH_MODE_SUPPORTED)
                wait_dsecs = fw_health->normal_func_wait_dsecs;
                bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
        }
+
+       bp->fw_reset_min_dsecs = fw_health->post_reset_wait_dsecs;
        bp->fw_reset_max_dsecs = fw_health->post_reset_max_wait_dsecs;
        bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
 }
        bnxt_rtnl_lock_sp(bp);
        if (test_bit(BNXT_STATE_OPEN, &bp->state) &&
            !test_bit(BNXT_STATE_IN_FW_RESET, &bp->state)) {
-               int n = 0;
+               int n = 0, tmo;
 
                set_bit(BNXT_STATE_IN_FW_RESET, &bp->state);
                if (bp->pf.active_vfs &&
                        goto fw_reset_exit;
                }
                bnxt_fw_reset_close(bp);
-               bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
-               bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10);
+               if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) {
+                       bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN;
+                       tmo = HZ / 10;
+               } else {
+                       bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
+                       tmo = bp->fw_reset_min_dsecs * HZ / 10;
+               }
+               bnxt_queue_fw_reset_work(bp, tmo);
        }
 fw_reset_exit:
        bnxt_rtnl_unlock_sp(bp);
        switch (bp->fw_reset_state) {
        case BNXT_FW_RESET_STATE_POLL_VF: {
                int n = bnxt_get_registered_vfs(bp);
+               int tmo;
 
                if (n < 0) {
                        netdev_err(bp->dev, "Firmware reset aborted, subsequent func_qcfg cmd failed, rc = %d, %d msecs since reset timestamp\n",
                bp->fw_reset_timestamp = jiffies;
                rtnl_lock();
                bnxt_fw_reset_close(bp);
-               bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
+               if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) {
+                       bp->fw_reset_state = BNXT_FW_RESET_STATE_POLL_FW_DOWN;
+                       tmo = HZ / 10;
+               } else {
+                       bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
+                       tmo = bp->fw_reset_min_dsecs * HZ / 10;
+               }
                rtnl_unlock();
-               bnxt_queue_fw_reset_work(bp, bp->fw_reset_min_dsecs * HZ / 10);
+               bnxt_queue_fw_reset_work(bp, tmo);
                return;
        }
+       case BNXT_FW_RESET_STATE_POLL_FW_DOWN: {
+               u32 val;
+
+               val = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG);
+               if (!(val & BNXT_FW_STATUS_SHUTDOWN) &&
+                   !time_after(jiffies, bp->fw_reset_timestamp +
+                   (bp->fw_reset_max_dsecs * HZ / 10))) {
+                       bnxt_queue_fw_reset_work(bp, HZ / 5);
+                       return;
+               }
+
+               if (!bp->fw_health->master) {
+                       u32 wait_dsecs = bp->fw_health->normal_func_wait_dsecs;
+
+                       bp->fw_reset_state = BNXT_FW_RESET_STATE_ENABLE_DEV;
+                       bnxt_queue_fw_reset_work(bp, wait_dsecs * HZ / 10);
+                       return;
+               }
+               bp->fw_reset_state = BNXT_FW_RESET_STATE_RESET_FW;
+       }
+       /* fall through */
        case BNXT_FW_RESET_STATE_RESET_FW: {
                u32 wait_dsecs = bp->fw_health->post_reset_wait_dsecs;
 
 
 #define BNXT_FW_HEALTH_WIN_MAP_OFF     8
 
 #define BNXT_FW_STATUS_HEALTHY         0x8000
+#define BNXT_FW_STATUS_SHUTDOWN                0x100000
 
 struct bnxt {
        void __iomem            *bar0;
        #define BNXT_FW_CAP_CFA_RFS_RING_TBL_IDX        0x00010000
        #define BNXT_FW_CAP_PCIE_STATS_SUPPORTED        0x00020000
        #define BNXT_FW_CAP_EXT_STATS_SUPPORTED         0x00040000
+       #define BNXT_FW_CAP_ERR_RECOVER_RELOAD          0x00100000
 
 #define BNXT_NEW_RM(bp)                ((bp)->fw_cap & BNXT_FW_CAP_NEW_RM)
        u32                     hwrm_spec_code;
 #define BNXT_FW_RESET_STATE_ENABLE_DEV 3
 #define BNXT_FW_RESET_STATE_POLL_FW    4
 #define BNXT_FW_RESET_STATE_OPENING    5
+#define BNXT_FW_RESET_STATE_POLL_FW_DOWN       6
 
        u16                     fw_reset_min_dsecs;
 #define BNXT_DFLT_FW_RST_MIN_DSECS     20