Commit 937f188c authored by Vasundhara Volam's avatar Vasundhara Volam Committed by David S. Miller

bnxt_en: Fix the logic that creates the health reporters.

Fix the logic to properly check the fw capabilities and create the
devlink health reporters only when needed.  The current code creates
the reporters unconditionally as long as bp->fw_health is valid, and
that's not correct.

Call bnxt_dl_fw_reporters_create() directly from the init and reset
code path instead of from bnxt_dl_register().  This allows the
reporters to be adjusted when capabilities change.  The same
applies to bnxt_dl_fw_reporters_destroy().

Fixes: 6763c779 ("bnxt_en: Add new FW devlink_health_reporter")
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 0797c10d
......@@ -10625,6 +10625,12 @@ static int bnxt_fw_init_one(struct bnxt *bp)
rc = bnxt_approve_mac(bp, bp->dev->dev_addr, false);
if (rc)
return rc;
/* In case fw capabilities have changed, destroy the unneeded
* reporters and create newly capable ones.
*/
bnxt_dl_fw_reporters_destroy(bp, false);
bnxt_dl_fw_reporters_create(bp);
bnxt_fw_init_one_p3(bp);
return 0;
}
......@@ -11413,6 +11419,7 @@ static void bnxt_remove_one(struct pci_dev *pdev)
if (BNXT_PF(bp)) {
bnxt_sriov_disable(bp);
bnxt_dl_fw_reporters_destroy(bp, true);
bnxt_dl_unregister(bp);
}
......@@ -11892,8 +11899,10 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
goto init_err_cleanup_tc;
if (BNXT_PF(bp))
if (BNXT_PF(bp)) {
bnxt_dl_register(bp);
bnxt_dl_fw_reporters_create(bp);
}
netdev_info(dev, "%s found at mem %lx, node addr %pM\n",
board_info[ent->driver_data].name,
......
......@@ -125,21 +125,15 @@ struct devlink_health_reporter_ops bnxt_dl_fw_fatal_reporter_ops = {
.recover = bnxt_fw_fatal_recover,
};
static void bnxt_dl_fw_reporters_create(struct bnxt *bp)
void bnxt_dl_fw_reporters_create(struct bnxt *bp)
{
struct bnxt_fw_health *health = bp->fw_health;
if (!health)
if (!bp->dl || !health)
return;
health->fw_reporter =
devlink_health_reporter_create(bp->dl, &bnxt_dl_fw_reporter_ops,
0, false, bp);
if (IS_ERR(health->fw_reporter)) {
netdev_warn(bp->dev, "Failed to create FW health reporter, rc = %ld\n",
PTR_ERR(health->fw_reporter));
health->fw_reporter = NULL;
}
if (!(bp->fw_cap & BNXT_FW_CAP_HOT_RESET) || health->fw_reset_reporter)
goto err_recovery;
health->fw_reset_reporter =
devlink_health_reporter_create(bp->dl,
......@@ -149,8 +143,30 @@ static void bnxt_dl_fw_reporters_create(struct bnxt *bp)
netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n",
PTR_ERR(health->fw_reset_reporter));
health->fw_reset_reporter = NULL;
bp->fw_cap &= ~BNXT_FW_CAP_HOT_RESET;
}
err_recovery:
if (!(bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY))
return;
if (!health->fw_reporter) {
health->fw_reporter =
devlink_health_reporter_create(bp->dl,
&bnxt_dl_fw_reporter_ops,
0, false, bp);
if (IS_ERR(health->fw_reporter)) {
netdev_warn(bp->dev, "Failed to create FW health reporter, rc = %ld\n",
PTR_ERR(health->fw_reporter));
health->fw_reporter = NULL;
bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
return;
}
}
if (health->fw_fatal_reporter)
return;
health->fw_fatal_reporter =
devlink_health_reporter_create(bp->dl,
&bnxt_dl_fw_fatal_reporter_ops,
......@@ -159,24 +175,35 @@ static void bnxt_dl_fw_reporters_create(struct bnxt *bp)
netdev_warn(bp->dev, "Failed to create FW fatal health reporter, rc = %ld\n",
PTR_ERR(health->fw_fatal_reporter));
health->fw_fatal_reporter = NULL;
bp->fw_cap &= ~BNXT_FW_CAP_ERROR_RECOVERY;
}
}
static void bnxt_dl_fw_reporters_destroy(struct bnxt *bp)
void bnxt_dl_fw_reporters_destroy(struct bnxt *bp, bool all)
{
struct bnxt_fw_health *health = bp->fw_health;
if (!health)
if (!bp->dl || !health)
return;
if (health->fw_reporter)
devlink_health_reporter_destroy(health->fw_reporter);
if (health->fw_reset_reporter)
if ((all || !(bp->fw_cap & BNXT_FW_CAP_HOT_RESET)) &&
health->fw_reset_reporter) {
devlink_health_reporter_destroy(health->fw_reset_reporter);
health->fw_reset_reporter = NULL;
}
if (health->fw_fatal_reporter)
if ((bp->fw_cap & BNXT_FW_CAP_ERROR_RECOVERY) && !all)
return;
if (health->fw_reporter) {
devlink_health_reporter_destroy(health->fw_reporter);
health->fw_reporter = NULL;
}
if (health->fw_fatal_reporter) {
devlink_health_reporter_destroy(health->fw_fatal_reporter);
health->fw_fatal_reporter = NULL;
}
}
void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event)
......@@ -502,8 +529,6 @@ int bnxt_dl_register(struct bnxt *bp)
devlink_params_publish(dl);
bnxt_dl_fw_reporters_create(bp);
return 0;
err_dl_port_unreg:
......@@ -526,7 +551,6 @@ void bnxt_dl_unregister(struct bnxt *bp)
if (!dl)
return;
bnxt_dl_fw_reporters_destroy(bp);
devlink_port_params_unregister(&bp->dl_port, bnxt_dl_port_params,
ARRAY_SIZE(bnxt_dl_port_params));
devlink_port_unregister(&bp->dl_port);
......
......@@ -58,6 +58,8 @@ struct bnxt_dl_nvm_param {
void bnxt_devlink_health_report(struct bnxt *bp, unsigned long event);
void bnxt_dl_health_status_update(struct bnxt *bp, bool healthy);
void bnxt_dl_fw_reporters_create(struct bnxt *bp);
void bnxt_dl_fw_reporters_destroy(struct bnxt *bp, bool all);
int bnxt_dl_register(struct bnxt *bp);
void bnxt_dl_unregister(struct bnxt *bp);
......
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