diff options
author | Pavan Chebbi <pavan.chebbi@broadcom.com> | 2020-12-13 06:51:44 -0500 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2020-12-14 18:52:43 -0800 |
commit | 2e5fb428a61ce58f9db6ceccdeb6dc292248f1dc (patch) | |
tree | bceec7b3d582ebe5483fd2d547f5fff3e57cd249 /drivers/net/ethernet/broadcom | |
parent | a9094ba6072bfabe93f93b641a3858d9c91c2c86 (diff) |
bnxt_en: Restructure bnxt_flash_package_from_fw_obj() to execute in a loop.
On NICs with a smaller NVRAM, FW installation may fail after multiple
updates due to fragmentation. The driver can retry when FW returns
a special error code. To faciliate the retry, we restructure the
logic that performs the flashing in a loop. The actual retry logic
will be added in the next patch.
Signed-off-by: Pavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/ethernet/broadcom')
-rw-r--r-- | drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c | 60 |
1 files changed, 28 insertions, 32 deletions
diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c index 7635ff84b928..fa4f9941498e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c @@ -2461,58 +2461,54 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware install_type >>= 16; install.install_type = cpu_to_le32(install_type); - rc = bnxt_find_nvram_item(dev, BNX_DIR_TYPE_UPDATE, - BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE, - &index, &item_len, NULL); - if (rc) { - netdev_err(dev, "PKG update area not created in nvram\n"); - return rc; - } + do { + rc = bnxt_find_nvram_item(dev, BNX_DIR_TYPE_UPDATE, + BNX_DIR_ORDINAL_FIRST, + BNX_DIR_EXT_NONE, + &index, &item_len, NULL); + if (rc) { + netdev_err(dev, "PKG update area not created in nvram\n"); + break; + } + if (fw->size > item_len) { + netdev_err(dev, "PKG insufficient update area in nvram: %lu\n", + (unsigned long)fw->size); + rc = -EFBIG; + break; + } - if (fw->size > item_len) { - netdev_err(dev, "PKG insufficient update area in nvram: %lu\n", - (unsigned long)fw->size); - rc = -EFBIG; - } else { modify.dir_idx = cpu_to_le16(index); modify.len = cpu_to_le32(fw->size); memcpy(kmem, fw->data, fw->size); rc = hwrm_send_message(bp, &modify, sizeof(modify), FLASH_PACKAGE_TIMEOUT); - } - if (rc) - goto err_exit; - - mutex_lock(&bp->hwrm_cmd_lock); - rc = _hwrm_send_message(bp, &install, sizeof(install), - INSTALL_PACKAGE_TIMEOUT); - memcpy(&resp, bp->hwrm_cmd_resp_addr, sizeof(resp)); + if (rc) + break; - if (rc) { - u8 error_code = ((struct hwrm_err_output *)&resp)->cmd_err; + mutex_lock(&bp->hwrm_cmd_lock); + rc = _hwrm_send_message(bp, &install, sizeof(install), + INSTALL_PACKAGE_TIMEOUT); + memcpy(&resp, bp->hwrm_cmd_resp_addr, sizeof(resp)); - if (resp.error_code && error_code == + if (rc && ((struct hwrm_err_output *)&resp)->cmd_err == NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR) { - install.flags |= cpu_to_le16( - NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); + install.flags |= + cpu_to_le16(NVM_INSTALL_UPDATE_REQ_FLAGS_ALLOWED_TO_DEFRAG); + rc = _hwrm_send_message(bp, &install, sizeof(install), INSTALL_PACKAGE_TIMEOUT); memcpy(&resp, bp->hwrm_cmd_resp_addr, sizeof(resp)); } - if (rc) - goto flash_pkg_exit; - } + mutex_unlock(&bp->hwrm_cmd_lock); + } while (false); + dma_free_coherent(&bp->pdev->dev, fw->size, kmem, dma_handle); if (resp.result) { netdev_err(dev, "PKG install error = %d, problem_item = %d\n", (s8)resp.result, (int)resp.problem_item); rc = -ENOPKG; } -flash_pkg_exit: - mutex_unlock(&bp->hwrm_cmd_lock); -err_exit: - dma_free_coherent(&bp->pdev->dev, fw->size, kmem, dma_handle); if (rc == -EACCES) bnxt_print_admin_err(bp); return rc; |