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 <vasundhara-v.volam@broadcom.com>
Signed-off-by: Edwin Peer <edwin.peer@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Edwin Peer 2020-10-04 15:22:54 -04:00 committed by David S. Miller
parent ba02629ff6
commit 87f7ab8d6f
1 changed files with 29 additions and 9 deletions

View File

@ -11035,6 +11035,21 @@ 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 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) static int bnxt_fw_init_one_p1(struct bnxt *bp)
{ {
int rc; int rc;
@ -11043,11 +11058,20 @@ static int bnxt_fw_init_one_p1(struct bnxt *bp)
rc = bnxt_hwrm_ver_get(bp); rc = bnxt_hwrm_ver_get(bp);
bnxt_try_map_fw_health_reg(bp); bnxt_try_map_fw_health_reg(bp);
if (rc) { 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, netdev_err(bp->dev,
"Firmware not responding, status: 0x%x\n", "Firmware not responding, status: 0x%x\n",
bnxt_fw_health_readl(bp, sts);
BNXT_FW_HEALTH_REG)); 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; return rc;
} }
@ -11221,12 +11245,8 @@ static void bnxt_reset_all(struct bnxt *bp)
int i, rc; int i, rc;
if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) { if (bp->fw_cap & BNXT_FW_CAP_ERR_RECOVER_RELOAD) {
#ifdef CONFIG_TEE_BNXT_FW bnxt_fw_reset_via_optee(bp);
rc = tee_bnxt_fw_load();
if (rc)
netdev_err(bp->dev, "Unable to reset FW rc=%d\n", rc);
bp->fw_reset_timestamp = jiffies; bp->fw_reset_timestamp = jiffies;
#endif
return; return;
} }