DPDK patches and discussions
 help / color / mirror / Atom feed
From: Andrew Rybchenko <arybchenko@solarflare.com>
To: <dev@dpdk.org>
Cc: Richard Houldsworth <rhouldsworth@solarflare.com>
Subject: [dpdk-dev] [PATCH 14/29] net/sfc/base: add background mode firmware updating
Date: Mon, 10 Jun 2019 08:38:29 +0100	[thread overview]
Message-ID: <1560152324-20538-15-git-send-email-arybchenko@solarflare.com> (raw)
In-Reply-To: <1560152324-20538-1-git-send-email-arybchenko@solarflare.com>

From: Richard Houldsworth <rhouldsworth@solarflare.com>

Request firmware updates be performed in background mode.
In this mode MCDI to the function processing the update
remains accessible and the client polls for completion.
This is supported for lengthy partition updates such as
MCFW and bundles. The MC ignores the flags used for this
mode for other partition updates.

Signed-off-by: Richard Houldsworth <rhouldsworth@solarflare.com>
Signed-off-by: Andrew Rybchenko <arybchenko@solarflare.com>
---
 drivers/net/sfc/base/ef10_nic.c    |  5 ++++
 drivers/net/sfc/base/ef10_nvram.c  | 55 ++++++++++++++++++++++++++++++++++----
 drivers/net/sfc/base/efx.h         |  2 ++
 drivers/net/sfc/base/efx_impl.h    |  4 +++
 drivers/net/sfc/base/efx_nvram.c   | 30 +++++++++++++++------
 drivers/net/sfc/base/siena_nvram.c |  4 ++-
 6 files changed, 86 insertions(+), 14 deletions(-)

diff --git a/drivers/net/sfc/base/ef10_nic.c b/drivers/net/sfc/base/ef10_nic.c
index 27508e1..4c90e10 100644
--- a/drivers/net/sfc/base/ef10_nic.c
+++ b/drivers/net/sfc/base/ef10_nic.c
@@ -1216,6 +1216,11 @@
 	else
 		encp->enc_nvram_update_verify_result_supported = B_FALSE;
 
+	if (CAP_FLAGS2(req, NVRAM_UPDATE_POLL_VERIFY_RESULT))
+		encp->enc_nvram_update_poll_verify_result_supported = B_TRUE;
+	else
+		encp->enc_nvram_update_poll_verify_result_supported = B_FALSE;
+
 	/*
 	 * Check if firmware update via the BUNDLE partition is supported
 	 */
diff --git a/drivers/net/sfc/base/ef10_nvram.c b/drivers/net/sfc/base/ef10_nvram.c
index 1fb7185..ed88e83 100644
--- a/drivers/net/sfc/base/ef10_nvram.c
+++ b/drivers/net/sfc/base/ef10_nvram.c
@@ -2177,6 +2177,10 @@ static uint32_t checksum_tlv_partition(
 	return (rc);
 }
 
+#define	EF10_NVRAM_INITIAL_POLL_DELAY_US 10000
+#define	EF10_NVRAM_MAX_POLL_DELAY_US     1000000
+#define	EF10_NVRAM_POLL_RETRIES          100
+
 	__checkReturn		efx_rc_t
 ef10_nvram_partn_unlock(
 	__in			efx_nic_t *enp,
@@ -2184,17 +2188,58 @@ static uint32_t checksum_tlv_partition(
 	__out_opt		uint32_t *verify_resultp)
 {
 	boolean_t reboot = B_FALSE;
+	uint32_t poll_delay_us = EF10_NVRAM_INITIAL_POLL_DELAY_US;
+	uint32_t poll_retry = 0;
+	uint32_t verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
 	efx_rc_t rc;
 
-	if (verify_resultp != NULL)
-		*verify_resultp = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
+	rc = efx_mcdi_nvram_update_finish(enp, partn, reboot,
+	    EFX_NVRAM_UPDATE_FLAGS_BACKGROUND, &verify_result);
 
-	rc = efx_mcdi_nvram_update_finish(enp, partn, reboot, verify_resultp);
-	if (rc != 0)
-		goto fail1;
+	/*
+	 * NVRAM updates can take a long time (e.g. up to 1 minute for bundle
+	 * images). Polling for NVRAM update completion ensures that other MCDI
+	 * commands can be issued before the background NVRAM update completes.
+	 *
+	 * Without polling, other MCDI commands can only be issued before the
+	 * NVRAM update completes if the MCDI transport and the firmware
+	 * support the Asynchronous MCDI protocol extensions in SF-116575-PS.
+	 *
+	 * The initial call either completes the update synchronously, or
+	 * returns RC_PENDING to indicate processing is continuing. In the
+	 * latter case, we poll for at least 1 minute, at increasing intervals
+	 * (10ms, 100ms, 1s).
+	 */
+	while (verify_result == MC_CMD_NVRAM_VERIFY_RC_PENDING) {
+
+		if (poll_retry > EF10_NVRAM_POLL_RETRIES) {
+			rc = ETIMEDOUT;
+			goto fail1;
+		}
+		poll_retry++;
+
+		EFSYS_SLEEP(poll_delay_us);
+		if (poll_delay_us < EF10_NVRAM_MAX_POLL_DELAY_US)
+			poll_delay_us *= 10;
+
+		/* Poll for completion of background NVRAM update. */
+		verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
+
+		rc = efx_mcdi_nvram_update_finish(enp, partn, reboot,
+		    EFX_NVRAM_UPDATE_FLAGS_POLL, &verify_result);
+		if (rc != 0) {
+			/* Poll failed, so assume NVRAM update failed. */
+			goto fail2;
+		}
+	}
+
+	if (verify_resultp != NULL)
+		*verify_resultp = verify_result;
 
 	return (0);
 
+fail2:
+	EFSYS_PROBE(fail2);
 fail1:
 	EFSYS_PROBE1(fail1, efx_rc_t, rc);
 
diff --git a/drivers/net/sfc/base/efx.h b/drivers/net/sfc/base/efx.h
index d46e650..4385379 100644
--- a/drivers/net/sfc/base/efx.h
+++ b/drivers/net/sfc/base/efx.h
@@ -1395,6 +1395,8 @@ enum {
 	uint32_t		enc_max_pcie_link_gen;
 	/* Firmware verifies integrity of NVRAM updates */
 	boolean_t		enc_nvram_update_verify_result_supported;
+	/* Firmware supports polled NVRAM updates on select partitions */
+	boolean_t		enc_nvram_update_poll_verify_result_supported;
 	/* Firmware accepts updates via the BUNDLE partition */
 	boolean_t		enc_nvram_bundle_update_supported;
 	/* Firmware support for extended MAC_STATS buffer */
diff --git a/drivers/net/sfc/base/efx_impl.h b/drivers/net/sfc/base/efx_impl.h
index d8cadda..067cec3 100644
--- a/drivers/net/sfc/base/efx_impl.h
+++ b/drivers/net/sfc/base/efx_impl.h
@@ -594,11 +594,15 @@
 	__in_bcount(size)	caddr_t data,
 	__in			size_t size);
 
+#define	EFX_NVRAM_UPDATE_FLAGS_BACKGROUND	0x00000001
+#define	EFX_NVRAM_UPDATE_FLAGS_POLL		0x00000002
+
 	__checkReturn		efx_rc_t
 efx_mcdi_nvram_update_finish(
 	__in			efx_nic_t *enp,
 	__in			uint32_t partn,
 	__in			boolean_t reboot,
+	__in			uint32_t flags,
 	__out_opt		uint32_t *verify_resultp);
 
 #if EFSYS_OPT_DIAG
diff --git a/drivers/net/sfc/base/efx_nvram.c b/drivers/net/sfc/base/efx_nvram.c
index 74dac41..5e7236c 100644
--- a/drivers/net/sfc/base/efx_nvram.c
+++ b/drivers/net/sfc/base/efx_nvram.c
@@ -965,6 +965,7 @@
 	__in			efx_nic_t *enp,
 	__in			uint32_t partn,
 	__in			boolean_t reboot,
+	__in			uint32_t flags,
 	__out_opt		uint32_t *verify_resultp)
 {
 	const efx_nic_cfg_t *encp = &enp->en_nic_cfg;
@@ -972,7 +973,7 @@
 	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_NVRAM_UPDATE_FINISH_V2_IN_LEN,
 		MC_CMD_NVRAM_UPDATE_FINISH_V2_OUT_LEN);
 	uint32_t verify_result = MC_CMD_NVRAM_VERIFY_RC_UNKNOWN;
-	efx_rc_t rc;
+	efx_rc_t rc = 0;
 
 	req.emr_cmd = MC_CMD_NVRAM_UPDATE_FINISH;
 	req.emr_in_buf = payload;
@@ -983,8 +984,19 @@
 	MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_TYPE, partn);
 	MCDI_IN_SET_DWORD(req, NVRAM_UPDATE_FINISH_V2_IN_REBOOT, reboot);
 
-	MCDI_IN_POPULATE_DWORD_1(req, NVRAM_UPDATE_FINISH_V2_IN_FLAGS,
-	    NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT, 1);
+	if (!encp->enc_nvram_update_poll_verify_result_supported) {
+		flags &= ~EFX_NVRAM_UPDATE_FLAGS_BACKGROUND;
+		flags &= ~EFX_NVRAM_UPDATE_FLAGS_POLL;
+	}
+
+	MCDI_IN_POPULATE_DWORD_3(req, NVRAM_UPDATE_FINISH_V2_IN_FLAGS,
+	    NVRAM_UPDATE_FINISH_V2_IN_FLAG_REPORT_VERIFY_RESULT,
+	    1,
+	    NVRAM_UPDATE_FINISH_V2_IN_FLAG_RUN_IN_BACKGROUND,
+	    (flags & EFX_NVRAM_UPDATE_FLAGS_BACKGROUND) ? 1 : 0,
+	    NVRAM_UPDATE_FINISH_V2_IN_FLAG_POLL_VERIFY_RESULT,
+	    (flags & EFX_NVRAM_UPDATE_FLAGS_POLL) ? 1 : 0
+	    );
 
 	efx_mcdi_execute(enp, &req);
 
@@ -1005,11 +1017,13 @@
 		    MCDI_OUT_DWORD(req, NVRAM_UPDATE_FINISH_V2_OUT_RESULT_CODE);
 	}
 
-	if ((encp->enc_nvram_update_verify_result_supported) &&
-	    (verify_result != MC_CMD_NVRAM_VERIFY_RC_SUCCESS)) {
-		/* Update verification failed */
-		rc = EINVAL;
-		goto fail3;
+	if (encp->enc_nvram_update_verify_result_supported) {
+		if ((verify_result != MC_CMD_NVRAM_VERIFY_RC_SUCCESS) &&
+		    (verify_result != MC_CMD_NVRAM_VERIFY_RC_PENDING)) {
+			/* Update verification failed */
+			rc = EINVAL;
+			goto fail3;
+		}
 	}
 
 	if (verify_resultp != NULL)
diff --git a/drivers/net/sfc/base/siena_nvram.c b/drivers/net/sfc/base/siena_nvram.c
index 47a8ca2..51e601e 100644
--- a/drivers/net/sfc/base/siena_nvram.c
+++ b/drivers/net/sfc/base/siena_nvram.c
@@ -174,6 +174,7 @@
 	__out_opt		uint32_t *verify_resultp)
 {
 	boolean_t reboot;
+	uint32_t flags = 0;
 	efx_rc_t rc;
 
 	/*
@@ -184,7 +185,8 @@
 		    partn == MC_CMD_NVRAM_TYPE_PHY_PORT1 ||
 		    partn == MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO);
 
-	rc = efx_mcdi_nvram_update_finish(enp, partn, reboot, verify_resultp);
+	rc = efx_mcdi_nvram_update_finish(enp, partn, reboot, flags,
+		    verify_resultp);
 	if (rc != 0)
 		goto fail1;
 
-- 
1.8.3.1


  parent reply	other threads:[~2019-06-10  7:39 UTC|newest]

Thread overview: 35+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-10  7:38 [dpdk-dev] [PATCH 00/29] net/sfc/base: update base driver Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 01/29] net/sfc/base: enable chained multicast on all EF10 cards Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 02/29] net/sfc/base: fix signed/unsigned mismatch errors Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 03/29] net/sfc/base: fix shift by more bits than field width Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 04/29] net/sfc/base: improve code style in sensors decoding Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 05/29] net/sfc/base: do not rely on indirect header inclusion Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 06/29] net/sfc/base: add driver version string registration Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 07/29] net/sfc/base: add capabilities for bundle partition support Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 08/29] net/sfc/base: add extensible NVRAM info function Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 09/29] net/sfc/base: add NVRAM info to API Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 10/29] net/sfc/base: update MCDI headers Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 11/29] net/sfc/base: add firmware ID header Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 12/29] net/sfc/base: support direct FW update for bundle partitions Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 13/29] net/sfc/base: transition to the extensible NVRAM info API Andrew Rybchenko
2019-06-10  7:38 ` Andrew Rybchenko [this message]
2019-06-10  7:38 ` [dpdk-dev] [PATCH 15/29] net/sfc/base: add definition of bundle metadata partition Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 16/29] net/sfc/base: add definition of OEM TLV Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 17/29] net/sfc/base: export the zero-based MCDI port number Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 18/29] net/sfc/base: introduce of EVB module for SR-IOV support Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 19/29] net/sfc/base: add MCDI wrappers for vPort and vSwitch in EVB Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 20/29] net/sfc/base: add EVB module vSwitch/vPort/vAdaptor ops Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 21/29] net/sfc/base: implement vSwitch create/destroy Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 22/29] net/sfc/base: factor out upstream port vAdaptor allocation Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 23/29] net/sfc/base: support data path with EVB module Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 24/29] net/sfc/base: support proxy auth operations for SR-IOV Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 25/29] net/sfc/base: implement proxy auth MCDI event handling Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 26/29] net/sfc/base: provide proxy APIs to client drivers Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 27/29] net/sfc/base: provide APIs to configure and reset vPort Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 28/29] net/sfc/base: provide API to fetch vPort statistics Andrew Rybchenko
2019-06-10  7:38 ` [dpdk-dev] [PATCH 29/29] net/sfc/base: add APIs for PTP privilege configuration Andrew Rybchenko
2019-06-18  7:52 ` [dpdk-dev] [PATCH 00/29] net/sfc/base: update base driver Ferruh Yigit
2019-06-23 22:37   ` Thomas Monjalon
2019-06-24  7:53     ` Andrew Rybchenko
2019-06-24 11:17       ` Ferruh Yigit
2019-06-24 13:07         ` Thomas Monjalon

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1560152324-20538-15-git-send-email-arybchenko@solarflare.com \
    --to=arybchenko@solarflare.com \
    --cc=dev@dpdk.org \
    --cc=rhouldsworth@solarflare.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).