net/bnxt: query firmware error recovery capabilities
In Driver initiated error recovery process, driver has to know about the registers offset and values to initiate FW reset. The HWRM command HWRM_ERROR_RECOVERY_QCFG is used to obtain all the registers and values required to initiate FW reset. This command response includes FW heart_beat register, health status register, Error counter register, register offsets and values to do chip reset if firmware crashes and becomes unresponsive. Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com> Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
This commit is contained in:
parent
2e88b08391
commit
f836242401
@ -343,6 +343,29 @@ struct bnxt_ctx_mem_info {
|
||||
#define US_PER_MS 1000
|
||||
#define NS_PER_US 1000
|
||||
|
||||
struct bnxt_error_recovery_info {
|
||||
/* All units in milliseconds */
|
||||
uint32_t driver_polling_freq;
|
||||
uint32_t master_func_wait_period;
|
||||
uint32_t normal_func_wait_period;
|
||||
uint32_t master_func_wait_period_after_reset;
|
||||
uint32_t max_bailout_time_after_reset;
|
||||
#define BNXT_FW_STATUS_REG 0
|
||||
#define BNXT_FW_HEARTBEAT_CNT_REG 1
|
||||
#define BNXT_FW_RECOVERY_CNT_REG 2
|
||||
#define BNXT_FW_RESET_INPROG_REG 3
|
||||
uint32_t status_regs[4];
|
||||
uint32_t reset_inprogress_reg_mask;
|
||||
#define BNXT_NUM_RESET_REG 16
|
||||
uint8_t reg_array_cnt;
|
||||
uint32_t reset_reg[BNXT_NUM_RESET_REG];
|
||||
uint32_t reset_reg_val[BNXT_NUM_RESET_REG];
|
||||
uint8_t delay_after_reset[BNXT_NUM_RESET_REG];
|
||||
#define BNXT_FLAG_ERROR_RECOVERY_HOST (1 << 0)
|
||||
#define BNXT_FLAG_ERROR_RECOVERY_CO_CPU (1 << 1)
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
#define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input)
|
||||
struct bnxt {
|
||||
void *bar0;
|
||||
@ -372,6 +395,7 @@ struct bnxt {
|
||||
#define BNXT_FLAG_FATAL_ERROR (1 << 16)
|
||||
#define BNXT_FLAG_FW_CAP_IF_CHANGE (1 << 17)
|
||||
#define BNXT_FLAG_IF_CHANGE_HOT_FW_RESET_DONE (1 << 18)
|
||||
#define BNXT_FLAG_FW_CAP_ERROR_RECOVERY (1 << 19)
|
||||
#define BNXT_FLAG_EXT_STATS_SUPPORTED (1 << 29)
|
||||
#define BNXT_FLAG_NEW_RM (1 << 30)
|
||||
#define BNXT_FLAG_INIT_DONE (1U << 31)
|
||||
@ -478,6 +502,9 @@ struct bnxt {
|
||||
|
||||
uint16_t fw_reset_min_msecs;
|
||||
uint16_t fw_reset_max_msecs;
|
||||
|
||||
/* Struct to hold adapter error recovery related info */
|
||||
struct bnxt_error_recovery_info *recovery_info;
|
||||
};
|
||||
|
||||
int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
|
||||
|
@ -4170,6 +4170,11 @@ static int bnxt_init_fw(struct bnxt *bp)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Get the adapter error recovery support info */
|
||||
rc = bnxt_hwrm_error_recovery_qcfg(bp);
|
||||
if (rc)
|
||||
bp->flags &= ~BNXT_FLAG_FW_CAP_ERROR_RECOVERY;
|
||||
|
||||
if (mtu >= RTE_ETHER_MIN_MTU && mtu <= BNXT_MAX_MTU &&
|
||||
mtu != bp->eth_dev->data->mtu)
|
||||
bp->eth_dev->data->mtu = mtu;
|
||||
@ -4328,9 +4333,15 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev)
|
||||
rc = bnxt_hwrm_func_driver_unregister(bp, 0);
|
||||
bp->flags &= ~BNXT_FLAG_REGISTERED;
|
||||
bnxt_free_ctx_mem(bp);
|
||||
if (!reconfig_dev)
|
||||
if (!reconfig_dev) {
|
||||
bnxt_free_hwrm_resources(bp);
|
||||
|
||||
if (bp->recovery_info != NULL) {
|
||||
rte_free(bp->recovery_info);
|
||||
bp->recovery_info = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -630,6 +630,13 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED)
|
||||
bp->flags |= BNXT_FLAG_EXT_STATS_SUPPORTED;
|
||||
|
||||
if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERROR_RECOVERY_CAPABLE) {
|
||||
bp->flags |= BNXT_FLAG_FW_CAP_ERROR_RECOVERY;
|
||||
PMD_DRV_LOG(DEBUG, "Adapter Error recovery SUPPORTED\n");
|
||||
} else {
|
||||
bp->flags &= ~BNXT_FLAG_FW_CAP_ERROR_RECOVERY;
|
||||
}
|
||||
|
||||
HWRM_UNLOCK();
|
||||
|
||||
return rc;
|
||||
@ -4701,3 +4708,89 @@ int bnxt_hwrm_if_change(struct bnxt *bp, bool up)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp)
|
||||
{
|
||||
struct hwrm_error_recovery_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
|
||||
struct bnxt_error_recovery_info *info = bp->recovery_info;
|
||||
struct hwrm_error_recovery_qcfg_input req = {0};
|
||||
uint32_t flags = 0;
|
||||
unsigned int i;
|
||||
int rc;
|
||||
|
||||
/* Older FW does not have error recovery support */
|
||||
if (!(bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY))
|
||||
return 0;
|
||||
|
||||
if (!info) {
|
||||
info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg",
|
||||
sizeof(*info), 0);
|
||||
bp->recovery_info = info;
|
||||
if (info == NULL)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
memset(info, 0, sizeof(*info));
|
||||
}
|
||||
|
||||
HWRM_PREP(req, ERROR_RECOVERY_QCFG, BNXT_USE_CHIMP_MB);
|
||||
|
||||
rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
|
||||
|
||||
HWRM_CHECK_RESULT();
|
||||
|
||||
flags = rte_le_to_cpu_32(resp->flags);
|
||||
if (flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_HOST)
|
||||
info->flags |= BNXT_FLAG_ERROR_RECOVERY_HOST;
|
||||
else if (flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_CO_CPU)
|
||||
info->flags |= BNXT_FLAG_ERROR_RECOVERY_CO_CPU;
|
||||
|
||||
if ((info->flags & BNXT_FLAG_ERROR_RECOVERY_CO_CPU) &&
|
||||
!(bp->flags & BNXT_FLAG_KONG_MB_EN)) {
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* FW returned values are in units of 100msec */
|
||||
info->driver_polling_freq =
|
||||
rte_le_to_cpu_32(resp->driver_polling_freq) * 100;
|
||||
info->master_func_wait_period =
|
||||
rte_le_to_cpu_32(resp->master_func_wait_period) * 100;
|
||||
info->normal_func_wait_period =
|
||||
rte_le_to_cpu_32(resp->normal_func_wait_period) * 100;
|
||||
info->master_func_wait_period_after_reset =
|
||||
rte_le_to_cpu_32(resp->master_func_wait_period_after_reset) * 100;
|
||||
info->max_bailout_time_after_reset =
|
||||
rte_le_to_cpu_32(resp->max_bailout_time_after_reset) * 100;
|
||||
info->status_regs[BNXT_FW_STATUS_REG] =
|
||||
rte_le_to_cpu_32(resp->fw_health_status_reg);
|
||||
info->status_regs[BNXT_FW_HEARTBEAT_CNT_REG] =
|
||||
rte_le_to_cpu_32(resp->fw_heartbeat_reg);
|
||||
info->status_regs[BNXT_FW_RECOVERY_CNT_REG] =
|
||||
rte_le_to_cpu_32(resp->fw_reset_cnt_reg);
|
||||
info->status_regs[BNXT_FW_RESET_INPROG_REG] =
|
||||
rte_le_to_cpu_32(resp->reset_inprogress_reg);
|
||||
info->reg_array_cnt =
|
||||
rte_le_to_cpu_32(resp->reg_array_cnt);
|
||||
|
||||
if (info->reg_array_cnt >= BNXT_NUM_RESET_REG) {
|
||||
rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
for (i = 0; i < info->reg_array_cnt; i++) {
|
||||
info->reset_reg[i] =
|
||||
rte_le_to_cpu_32(resp->reset_reg[i]);
|
||||
info->reset_reg_val[i] =
|
||||
rte_le_to_cpu_32(resp->reset_reg_val[i]);
|
||||
info->delay_after_reset[i] =
|
||||
resp->delay_after_reset[i];
|
||||
}
|
||||
err:
|
||||
HWRM_UNLOCK();
|
||||
|
||||
if (rc) {
|
||||
rte_free(bp->recovery_info);
|
||||
bp->recovery_info = NULL;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
@ -202,4 +202,5 @@ int bnxt_hwrm_tunnel_redirect_info(struct bnxt *bp, uint8_t tun_type,
|
||||
uint16_t *dst_fid);
|
||||
int bnxt_hwrm_set_mac(struct bnxt *bp);
|
||||
int bnxt_hwrm_if_change(struct bnxt *bp, bool state);
|
||||
int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp);
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user