Commit 8280b38e authored by Vasundhara Volam's avatar Vasundhara Volam Committed by David S. Miller

bnxt_en: Fix bp->fw_health allocation and free logic.

bp->fw_health needs to be allocated for either the firmware initiated
reset feature or the driver initiated error recovery feature.  The
current code is not allocating bp->fw_health for all the necessary cases.
This patch corrects the logic to allocate bp->fw_health correctly when
needed.  If allocation fails, we clear the feature flags.

We also add the the missing kfree(bp->fw_health) when the driver is
unloaded.  If we get an async reset message from the firmware, we also
need to make sure that we have a valid bp->fw_health before proceeding.

Fixes: 07f83d72 ("bnxt_en: Discover firmware error recovery capabilities.")
Signed-off-by: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c74751f4
...@@ -2001,6 +2001,9 @@ static int bnxt_async_event_process(struct bnxt *bp, ...@@ -2001,6 +2001,9 @@ static int bnxt_async_event_process(struct bnxt *bp,
case ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: { case ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: {
u32 data1 = le32_to_cpu(cmpl->event_data1); u32 data1 = le32_to_cpu(cmpl->event_data1);
if (!bp->fw_health)
goto async_event_process_exit;
bp->fw_reset_timestamp = jiffies; bp->fw_reset_timestamp = jiffies;
bp->fw_reset_min_dsecs = cmpl->timestamp_lo; bp->fw_reset_min_dsecs = cmpl->timestamp_lo;
if (!bp->fw_reset_min_dsecs) if (!bp->fw_reset_min_dsecs)
...@@ -4421,8 +4424,9 @@ int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap, int bmap_size, ...@@ -4421,8 +4424,9 @@ int bnxt_hwrm_func_drv_rgtr(struct bnxt *bp, unsigned long *bmap, int bmap_size,
FUNC_DRV_RGTR_REQ_ENABLES_ASYNC_EVENT_FWD); FUNC_DRV_RGTR_REQ_ENABLES_ASYNC_EVENT_FWD);
req.os_type = cpu_to_le16(FUNC_DRV_RGTR_REQ_OS_TYPE_LINUX); req.os_type = cpu_to_le16(FUNC_DRV_RGTR_REQ_OS_TYPE_LINUX);
flags = FUNC_DRV_RGTR_REQ_FLAGS_16BIT_VER_MODE | flags = FUNC_DRV_RGTR_REQ_FLAGS_16BIT_VER_MODE;
FUNC_DRV_RGTR_REQ_FLAGS_HOT_RESET_SUPPORT; if (bp->fw_cap & BNXT_FW_CAP_HOT_RESET)
flags |= FUNC_DRV_RGTR_REQ_FLAGS_HOT_RESET_SUPPORT;
if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) if (bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY)
flags |= FUNC_DRV_RGTR_REQ_FLAGS_ERROR_RECOVERY_SUPPORT | flags |= FUNC_DRV_RGTR_REQ_FLAGS_ERROR_RECOVERY_SUPPORT |
FUNC_DRV_RGTR_REQ_FLAGS_MASTER_SUPPORT; FUNC_DRV_RGTR_REQ_FLAGS_MASTER_SUPPORT;
...@@ -7115,14 +7119,6 @@ static int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) ...@@ -7115,14 +7119,6 @@ static int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp)
rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT); rc = _hwrm_send_message(bp, &req, sizeof(req), HWRM_CMD_TIMEOUT);
if (rc) if (rc)
goto err_recovery_out; goto err_recovery_out;
if (!fw_health) {
fw_health = kzalloc(sizeof(*fw_health), GFP_KERNEL);
bp->fw_health = fw_health;
if (!fw_health) {
rc = -ENOMEM;
goto err_recovery_out;
}
}
fw_health->flags = le32_to_cpu(resp->flags); fw_health->flags = le32_to_cpu(resp->flags);
if ((fw_health->flags & ERROR_RECOVERY_QCFG_RESP_FLAGS_CO_CPU) && if ((fw_health->flags & ERROR_RECOVERY_QCFG_RESP_FLAGS_CO_CPU) &&
!(bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL)) { !(bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL)) {
...@@ -10485,6 +10481,23 @@ static void bnxt_init_dflt_coal(struct bnxt *bp) ...@@ -10485,6 +10481,23 @@ static void bnxt_init_dflt_coal(struct bnxt *bp)
bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS; bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS;
} }
static void bnxt_alloc_fw_health(struct bnxt *bp)
{
if (bp->fw_health)
return;
if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET) &&
!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY))
return;
bp->fw_health = kzalloc(sizeof(*bp->fw_health), GFP_KERNEL);
if (!bp->fw_health) {
netdev_warn(bp->dev, "Failed to allocate fw_health\n");
bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET;
bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
}
}
static int bnxt_fw_init_one_p1(struct bnxt *bp) static int bnxt_fw_init_one_p1(struct bnxt *bp)
{ {
int rc; int rc;
...@@ -10531,6 +10544,7 @@ static int bnxt_fw_init_one_p2(struct bnxt *bp) ...@@ -10531,6 +10544,7 @@ static int bnxt_fw_init_one_p2(struct bnxt *bp)
netdev_warn(bp->dev, "hwrm query adv flow mgnt failure rc: %d\n", netdev_warn(bp->dev, "hwrm query adv flow mgnt failure rc: %d\n",
rc); rc);
bnxt_alloc_fw_health(bp);
rc = bnxt_hwrm_error_recovery_qcfg(bp); rc = bnxt_hwrm_error_recovery_qcfg(bp);
if (rc) if (rc)
netdev_warn(bp->dev, "hwrm query error recovery failure rc: %d\n", netdev_warn(bp->dev, "hwrm query error recovery failure rc: %d\n",
...@@ -11418,6 +11432,8 @@ static void bnxt_remove_one(struct pci_dev *pdev) ...@@ -11418,6 +11432,8 @@ static void bnxt_remove_one(struct pci_dev *pdev)
bnxt_dcb_free(bp); bnxt_dcb_free(bp);
kfree(bp->edev); kfree(bp->edev);
bp->edev = NULL; bp->edev = NULL;
kfree(bp->fw_health);
bp->fw_health = NULL;
bnxt_cleanup_pci(bp); bnxt_cleanup_pci(bp);
bnxt_free_ctx_mem(bp); bnxt_free_ctx_mem(bp);
kfree(bp->ctx); kfree(bp->ctx);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment