mirror of https://gitee.com/openkylin/linux.git
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>
This commit is contained in:
parent
a9094ba607
commit
2e5fb428a6
|
@ -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);
|
||||
|
||||
do {
|
||||
rc = bnxt_find_nvram_item(dev, BNX_DIR_TYPE_UPDATE,
|
||||
BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
|
||||
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;
|
||||
break;
|
||||
}
|
||||
|
||||
if (fw->size > item_len) {
|
||||
netdev_err(dev, "PKG insufficient update area in nvram: %lu\n",
|
||||
(unsigned long)fw->size);
|
||||
rc = -EFBIG;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
break;
|
||||
|
||||
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) {
|
||||
u8 error_code = ((struct hwrm_err_output *)&resp)->cmd_err;
|
||||
|
||||
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;
|
||||
|
|
Loading…
Reference in New Issue