From 87f7ab8d6f88cc594e3417fd0a7238b9c72e88eb Mon Sep 17 00:00:00 2001 From: Edwin Peer Date: Sun, 4 Oct 2020 15:22:54 -0400 Subject: [PATCH] bnxt_en: perform no master recovery during startup The NS3 SoC platforms require assistance from the OP-TEE to recover firmware if a crash occurs while no driver is bound. The CRASHED_NO_MASTER condition is recorded in the firmware status register during the crash to indicate when driver intervension is needed to coordinate a firmware reload. This condition is detected during early driver initialization in order to effect a firmware fastboot on supported platforms when necessary. Reviewed-by: Vasundhara Volam Signed-off-by: Edwin Peer Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 38 +++++++++++++++++------ 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 224f76e784b8..afa425375cd0 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -11035,6 +11035,21 @@ static void bnxt_init_dflt_coal(struct bnxt *bp) bp->stats_coal_ticks = BNXT_DEF_STATS_COAL_TICKS; } +static int bnxt_fw_reset_via_optee(struct bnxt *bp) +{ +#ifdef CONFIG_TEE_BNXT_FW + int rc = tee_bnxt_fw_load(); + + if (rc) + netdev_err(bp->dev, "Failed FW reset via OP-TEE, rc=%d\n", rc); + + return rc; +#else + netdev_err(bp->dev, "OP-TEE not supported\n"); + return -ENODEV; +#endif +} + static int bnxt_fw_init_one_p1(struct bnxt *bp) { int rc; @@ -11043,12 +11058,21 @@ static int bnxt_fw_init_one_p1(struct bnxt *bp) rc = bnxt_hwrm_ver_get(bp); bnxt_try_map_fw_health_reg(bp); if (rc) { - if (bp->fw_health && bp->fw_health->status_reliable) + if (bp->fw_health && bp->fw_health->status_reliable) { + u32 sts = bnxt_fw_health_readl(bp, BNXT_FW_HEALTH_REG); + netdev_err(bp->dev, "Firmware not responding, status: 0x%x\n", - bnxt_fw_health_readl(bp, - BNXT_FW_HEALTH_REG)); - return rc; + sts); + if (sts & FW_STATUS_REG_CRASHED_NO_MASTER) { + netdev_warn(bp->dev, "Firmware recover via OP-TEE requested\n"); + rc = bnxt_fw_reset_via_optee(bp); + if (!rc) + rc = bnxt_hwrm_ver_get(bp); + } + } + if (rc) + return rc; } if (bp->fw_cap & BNXT_FW_CAP_KONG_MB_CHNL) { @@ -11221,12 +11245,8 @@ static void bnxt_reset_all(struct bnxt *bp) int i, rc; if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { -#ifdef CONFIG_TEE_BNXT_FW - rc = tee_bnxt_fw_load(); - if (rc) - netdev_err(bp->dev, "Unable to reset FW rc=%d\n", rc); + bnxt_fw_reset_via_optee(bp); bp->fw_reset_timestamp = jiffies; -#endif return; } -- 2.34.1