bnxt_en: check and resize NVRAM UPDATE entry before flashing
authorVikas Gupta <vikas.gupta@broadcom.com>
Fri, 21 Oct 2022 06:37:23 +0000 (02:37 -0400)
committerJakub Kicinski <kuba@kernel.org>
Tue, 25 Oct 2022 02:24:14 +0000 (19:24 -0700)
Resize of the UPDATE entry is required if the image to
be flashed is larger than the available space. Add this step,
otherwise flashing larger firmware images by ethtool or devlink
may fail.

Reviewed-by: Andy Gospodarek <andrew.gospodarek@broadcom.com>
Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c

index 44b715c..cc89e5e 100644 (file)
@@ -2514,6 +2514,7 @@ static int bnxt_flash_firmware_from_file(struct net_device *dev,
 #define MSG_INTERNAL_ERR "PKG install error : Internal error"
 #define MSG_NO_PKG_UPDATE_AREA_ERR "PKG update area not created in nvram"
 #define MSG_NO_SPACE_ERR "PKG insufficient update area in nvram"
+#define MSG_RESIZE_UPDATE_ERR "Resize UPDATE entry error"
 #define MSG_ANTI_ROLLBACK_ERR "HWRM_NVM_INSTALL_UPDATE failure due to Anti-rollback detected"
 #define MSG_GENERIC_FAILURE_ERR "HWRM_NVM_INSTALL_UPDATE failure"
 
@@ -2564,6 +2565,32 @@ static int nvm_update_err_to_stderr(struct net_device *dev, u8 result,
 #define BNXT_NVM_MORE_FLAG     (cpu_to_le16(NVM_MODIFY_REQ_FLAGS_BATCH_MODE))
 #define BNXT_NVM_LAST_FLAG     (cpu_to_le16(NVM_MODIFY_REQ_FLAGS_BATCH_LAST))
 
+static int bnxt_resize_update_entry(struct net_device *dev, size_t fw_size,
+                                   struct netlink_ext_ack *extack)
+{
+       u32 item_len;
+       int rc;
+
+       rc = bnxt_find_nvram_item(dev, BNX_DIR_TYPE_UPDATE,
+                                 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE, NULL,
+                                 &item_len, NULL);
+       if (rc) {
+               BNXT_NVM_ERR_MSG(dev, extack, MSG_NO_PKG_UPDATE_AREA_ERR);
+               return rc;
+       }
+
+       if (fw_size > item_len) {
+               rc = bnxt_flash_nvram(dev, BNX_DIR_TYPE_UPDATE,
+                                     BNX_DIR_ORDINAL_FIRST, 0, 1,
+                                     round_up(fw_size, 4096), NULL, 0);
+               if (rc) {
+                       BNXT_NVM_ERR_MSG(dev, extack, MSG_RESIZE_UPDATE_ERR);
+                       return rc;
+               }
+       }
+       return 0;
+}
+
 int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware *fw,
                                   u32 install_type, struct netlink_ext_ack *extack)
 {
@@ -2580,6 +2607,11 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware
        u16 index;
        int rc;
 
+       /* resize before flashing larger image than available space */
+       rc = bnxt_resize_update_entry(dev, fw->size, extack);
+       if (rc)
+               return rc;
+
        bnxt_hwrm_fw_set_time(bp);
 
        rc = hwrm_req_init(bp, modify, HWRM_NVM_MODIFY);