Commit ab0bed4b authored by Kalesh AP's avatar Kalesh AP Committed by David S. Miller

bnxt_en: parse and report result field when NVRAM package install fails

Instead of always returning -ENOPKG, decode the firmware error
code further when the HWRM_NVM_INSTALL_UPDATE firmware call fails.
Return a more suitable error code to userspace and log an error
in dmesg.

This is version 2 of the earlier patch that was reverted:

02acd399 ("bnxt_en: parse result field when NVRAM package install fails")

In this new version, if the call is made through devlink instead of
ethtool, we'll also set the error message in extack.

Link: https://lore.kernel.org/netdev/20220307141358.4d52462e@kicinski-fedora-pc1c0hjn.dhcp.thefacebook.com/Reviewed-by: default avatarSomnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: default avatarPavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: default avatarKalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 66ed81dc
......@@ -45,7 +45,7 @@ bnxt_dl_flash_update(struct devlink *dl,
}
devlink_flash_update_status_notify(dl, "Preparing to flash", NULL, 0, 0);
rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0);
rc = bnxt_flash_package_from_fw_obj(bp->dev, params->fw, 0, extack);
if (!rc)
devlink_flash_update_status_notify(dl, "Flashing done", NULL, 0, 0);
else
......
......@@ -23,6 +23,7 @@
#include <linux/ptp_clock_kernel.h>
#include <linux/net_tstamp.h>
#include <linux/timecounter.h>
#include <net/netlink.h>
#include "bnxt_hsi.h"
#include "bnxt.h"
#include "bnxt_hwrm.h"
......@@ -34,6 +35,13 @@
#include "bnxt_fw_hdr.h" /* Firmware hdr constant and structure defs */
#include "bnxt_coredump.h"
#define BNXT_NVM_ERR_MSG(dev, extack, msg) \
do { \
if (extack) \
NL_SET_ERR_MSG_MOD(extack, msg); \
netdev_err(dev, "%s\n", msg); \
} while (0)
static u32 bnxt_get_msglevel(struct net_device *dev)
{
struct bnxt *bp = netdev_priv(dev);
......@@ -2499,12 +2507,65 @@ static int bnxt_flash_firmware_from_file(struct net_device *dev,
return rc;
}
#define MSG_INTEGRITY_ERR "PKG install error : Data integrity on NVM"
#define MSG_INVALID_PKG "PKG install error : Invalid package"
#define MSG_AUTHENTICATION_ERR "PKG install error : Authentication error"
#define MSG_INVALID_DEV "PKG install error : Invalid device"
#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_ANTI_ROLLBACK_ERR "HWRM_NVM_INSTALL_UPDATE failure due to Anti-rollback detected"
#define MSG_GENERIC_FAILURE_ERR "HWRM_NVM_INSTALL_UPDATE failure"
static int nvm_update_err_to_stderr(struct net_device *dev, u8 result,
struct netlink_ext_ack *extack)
{
switch (result) {
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_TYPE_PARAMETER:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_INDEX_PARAMETER:
case NVM_INSTALL_UPDATE_RESP_RESULT_INSTALL_DATA_ERROR:
case NVM_INSTALL_UPDATE_RESP_RESULT_INSTALL_CHECKSUM_ERROR:
case NVM_INSTALL_UPDATE_RESP_RESULT_ITEM_NOT_FOUND:
case NVM_INSTALL_UPDATE_RESP_RESULT_ITEM_LOCKED:
BNXT_NVM_ERR_MSG(dev, extack, MSG_INTEGRITY_ERR);
return -EINVAL;
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_PREREQUISITE:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_FILE_HEADER:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_SIGNATURE:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_PROP_STREAM:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_PROP_LENGTH:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_MANIFEST:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_TRAILER:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_CHECKSUM:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_ITEM_CHECKSUM:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_DATA_LENGTH:
case NVM_INSTALL_UPDATE_RESP_RESULT_INVALID_DIRECTIVE:
case NVM_INSTALL_UPDATE_RESP_RESULT_DUPLICATE_ITEM:
case NVM_INSTALL_UPDATE_RESP_RESULT_ZERO_LENGTH_ITEM:
BNXT_NVM_ERR_MSG(dev, extack, MSG_INVALID_PKG);
return -ENOPKG;
case NVM_INSTALL_UPDATE_RESP_RESULT_INSTALL_AUTHENTICATION_ERROR:
BNXT_NVM_ERR_MSG(dev, extack, MSG_AUTHENTICATION_ERR);
return -EPERM;
case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_CHIP_REV:
case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_DEVICE_ID:
case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_SUBSYS_VENDOR:
case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_SUBSYS_ID:
case NVM_INSTALL_UPDATE_RESP_RESULT_UNSUPPORTED_PLATFORM:
BNXT_NVM_ERR_MSG(dev, extack, MSG_INVALID_DEV);
return -EOPNOTSUPP;
default:
BNXT_NVM_ERR_MSG(dev, extack, MSG_INTERNAL_ERR);
return -EIO;
}
}
#define BNXT_PKG_DMA_SIZE 0x40000
#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))
int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware *fw,
u32 install_type)
u32 install_type, struct netlink_ext_ack *extack)
{
struct hwrm_nvm_install_update_input *install;
struct hwrm_nvm_install_update_output *resp;
......@@ -2567,12 +2628,11 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware
BNX_DIR_EXT_NONE,
&index, &item_len, NULL);
if (rc) {
netdev_err(dev, "PKG update area not created in nvram\n");
BNXT_NVM_ERR_MSG(dev, extack, MSG_NO_PKG_UPDATE_AREA_ERR);
break;
}
if (fw->size > item_len) {
netdev_err(dev, "PKG insufficient update area in nvram: %lu\n",
(unsigned long)fw->size);
BNXT_NVM_ERR_MSG(dev, extack, MSG_NO_SPACE_ERR);
rc = -EFBIG;
break;
}
......@@ -2613,7 +2673,7 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware
switch (cmd_err) {
case NVM_INSTALL_UPDATE_CMD_ERR_CODE_ANTI_ROLLBACK:
netdev_err(dev, "HWRM_NVM_INSTALL_UPDATE failure Anti-rollback detected\n");
BNXT_NVM_ERR_MSG(dev, extack, MSG_ANTI_ROLLBACK_ERR);
rc = -EALREADY;
break;
case NVM_INSTALL_UPDATE_CMD_ERR_CODE_FRAG_ERR:
......@@ -2641,8 +2701,7 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware
}
fallthrough;
default:
netdev_err(dev, "HWRM_NVM_INSTALL_UPDATE failure rc :%x cmd_err :%x\n",
rc, cmd_err);
BNXT_NVM_ERR_MSG(dev, extack, MSG_GENERIC_FAILURE_ERR);
}
} while (defrag_attempted && !rc);
......@@ -2653,7 +2712,7 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware
if (resp->result) {
netdev_err(dev, "PKG install error = %d, problem_item = %d\n",
(s8)resp->result, (int)resp->problem_item);
rc = -ENOPKG;
rc = nvm_update_err_to_stderr(dev, resp->result, extack);
}
if (rc == -EACCES)
bnxt_print_admin_err(bp);
......@@ -2661,7 +2720,7 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware
}
static int bnxt_flash_package_from_file(struct net_device *dev, const char *filename,
u32 install_type)
u32 install_type, struct netlink_ext_ack *extack)
{
const struct firmware *fw;
int rc;
......@@ -2673,7 +2732,7 @@ static int bnxt_flash_package_from_file(struct net_device *dev, const char *file
return rc;
}
rc = bnxt_flash_package_from_fw_obj(dev, fw, install_type);
rc = bnxt_flash_package_from_fw_obj(dev, fw, install_type, extack);
release_firmware(fw);
......@@ -2691,7 +2750,7 @@ static int bnxt_flash_device(struct net_device *dev,
if (flash->region == ETHTOOL_FLASH_ALL_REGIONS ||
flash->region > 0xffff)
return bnxt_flash_package_from_file(dev, flash->data,
flash->region);
flash->region, NULL);
return bnxt_flash_firmware_from_file(dev, flash->region, flash->data);
}
......
......@@ -54,7 +54,7 @@ int bnxt_hwrm_nvm_get_dev_info(struct bnxt *bp,
int bnxt_hwrm_firmware_reset(struct net_device *dev, u8 proc_type,
u8 self_reset, u8 flags);
int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware *fw,
u32 install_type);
u32 install_type, struct netlink_ext_ack *extack);
int bnxt_get_pkginfo(struct net_device *dev, char *ver, int size);
void bnxt_ethtool_init(struct bnxt *bp);
void bnxt_ethtool_free(struct bnxt *bp);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment