Commit 87f7ab8d authored by Edwin Peer's avatar Edwin Peer Committed by David S. Miller
Browse files

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: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Signed-off-by: default avatarEdwin Peer <edwin.peer@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent ba02629f
Loading
Loading
Loading
Loading
+29 −9
Original line number Diff line number Diff line
@@ -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,11 +11058,20 @@ 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));
				   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;
	}

@@ -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;
	}