From patchwork Mon Jun 10 07:38:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Rybchenko X-Patchwork-Id: 54591 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 83AD61BEC7; Mon, 10 Jun 2019 09:39:11 +0200 (CEST) Received: from dispatch1-us1.ppe-hosted.com (dispatch1-us1.ppe-hosted.com [67.231.154.164]) by dpdk.org (Postfix) with ESMTP id 8A6451BE8C for ; Mon, 10 Jun 2019 09:38:55 +0200 (CEST) X-Virus-Scanned: Proofpoint Essentials engine Received: from webmail.solarflare.com (webmail.solarflare.com [12.187.104.26]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (No client certificate requested) by mx1-us5.ppe-hosted.com (PPE Hosted ESMTP Server) with ESMTPS id 90E084C005C for ; Mon, 10 Jun 2019 07:38:54 +0000 (UTC) Received: from ocex03.SolarFlarecom.com (10.20.40.36) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Mon, 10 Jun 2019 00:38:51 -0700 Received: from opal.uk.solarflarecom.com (10.17.10.1) by ocex03.SolarFlarecom.com (10.20.40.36) with Microsoft SMTP Server (TLS) id 15.0.1395.4 via Frontend Transport; Mon, 10 Jun 2019 00:38:50 -0700 Received: from ukv-loginhost.uk.solarflarecom.com (ukv-loginhost.uk.solarflarecom.com [10.17.10.39]) by opal.uk.solarflarecom.com (8.13.8/8.13.8) with ESMTP id x5A7cnjb008806; Mon, 10 Jun 2019 08:38:49 +0100 Received: from ukv-loginhost.uk.solarflarecom.com (localhost [127.0.0.1]) by ukv-loginhost.uk.solarflarecom.com (Postfix) with ESMTP id A38481616E0; Mon, 10 Jun 2019 08:38:49 +0100 (BST) From: Andrew Rybchenko To: CC: Richard Houldsworth Date: Mon, 10 Jun 2019 08:38:29 +0100 Message-ID: <1560152324-20538-15-git-send-email-arybchenko@solarflare.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1560152324-20538-1-git-send-email-arybchenko@solarflare.com> References: <1560152324-20538-1-git-send-email-arybchenko@solarflare.com> MIME-Version: 1.0 X-TM-AS-Product-Ver: SMEX-12.5.0.1300-8.5.1010-24664.003 X-TM-AS-Result: No-15.471200-4.000000-10 X-TMASE-MatchedRID: UeLhfUocf5u5UpxrNQf5nR/R5SKe31ARy733NwuklsLg91xayX4L83J4 YYfr3pskJntVNHapMCsD6grIvl1lOkASN/wlEVscuwdUMMznEA+XP9dn/qaMz1OitEi5p2m0cij MZrr2iZ2t2gtuWr1LmnvLDtlx1Xxa42nbKJncaZSnRPnrtF/XIQRryDXHx6oXVWQnHKxp38iRZu wKslcgBU1SWuwykreXqlMM2MiEo9aDbvXKFJb+1B2atUdrgMZMovA/6ONsv0qtyIlQ9jhSMS93G 1kmDedMnGIq66JZ5o7Fw+98ljZmfn/so8z8CegQJP29N7gUd1CC7C2rJeUToXU98taw1P0pcjAQ JWA5qeJIFVQy1Tw7a7hGuSgz3a9tEHQGT9GzE46fG8+bi+/3vFxo0H+7nJCrFL5/d3sGIoLxMS4 fSSByxvTWkT7dqxIUhwbJr5e+6PKtiF+p+9BY6TCMW7zNwFaIurOlC+PL0QBefydTdBeegaPFjJ EFr+olwXCBO/GKkVqOhzOa6g8KrZRMZUCEHkRt X-TM-AS-User-Approved-Sender: No X-TM-AS-User-Blocked-Sender: No X-TMASE-Result: 10--15.471200-4.000000 X-TMASE-Version: SMEX-12.5.0.1300-8.5.1010-24664.003 X-MDID: 1560152335-Jk3Octes1WUA Subject: [dpdk-dev] [PATCH 14/29] net/sfc/base: add background mode firmware updating X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Richard Houldsworth 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 Signed-off-by: Andrew Rybchenko --- 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;