Thomas Bogendoerfer eda5f2
From: Vikas Gupta <vikas.gupta@broadcom.com>
Thomas Bogendoerfer eda5f2
Date: Fri, 29 Oct 2021 03:47:55 -0400
Thomas Bogendoerfer eda5f2
Subject: bnxt_en: Provide stored devlink "fw" version on older firmware
Thomas Bogendoerfer eda5f2
Patch-mainline: v5.16-rc1
Thomas Bogendoerfer eda5f2
Git-commit: 63185eb3aa267f2844580bbd8c9c1c97516f5dbb
Thomas Bogendoerfer eda5f2
References: jsc#SLE-18978
Thomas Bogendoerfer eda5f2
Thomas Bogendoerfer eda5f2
On older firmware that doesn't support the HWRM_NVM_GET_DEV_INFO
Thomas Bogendoerfer eda5f2
command that returns detailed stored firmware versions, fallback
Thomas Bogendoerfer eda5f2
to use the same firmware package version that is reported to ethtool.
Thomas Bogendoerfer eda5f2
Refactor bnxt_get_pkgver() in bnxt_ethtool.c so that devlink can call
Thomas Bogendoerfer eda5f2
and get the package version.
Thomas Bogendoerfer eda5f2
Thomas Bogendoerfer eda5f2
Signed-off-by: Vikas Gupta <vikas.gupta@broadcom.com>
Thomas Bogendoerfer eda5f2
Reviewed-by: Edwin Peer <edwin.peer@broadcom.com>
Thomas Bogendoerfer eda5f2
Signed-off-by: Michael Chan <michael.chan@broadcom.com>
Thomas Bogendoerfer eda5f2
Signed-off-by: David S. Miller <davem@davemloft.net>
Thomas Bogendoerfer eda5f2
Acked-by: Thomas Bogendoerfer <tbogendoerfer@suse.de>
Thomas Bogendoerfer eda5f2
---
Thomas Bogendoerfer eda5f2
 drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c |    7 +++
Thomas Bogendoerfer eda5f2
 drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c |   41 +++++++++++++++-------
Thomas Bogendoerfer eda5f2
 drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h |    1 
Thomas Bogendoerfer eda5f2
 3 files changed, 36 insertions(+), 13 deletions(-)
Thomas Bogendoerfer eda5f2
Thomas Bogendoerfer eda5f2
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
Thomas Bogendoerfer eda5f2
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c
Thomas Bogendoerfer eda5f2
@@ -915,8 +915,13 @@ static int bnxt_dl_info_get(struct devli
Thomas Bogendoerfer eda5f2
 
Thomas Bogendoerfer eda5f2
 	rc = bnxt_hwrm_nvm_get_dev_info(bp, &nvm_dev_info);
Thomas Bogendoerfer eda5f2
 	if (rc ||
Thomas Bogendoerfer eda5f2
-	    !(nvm_dev_info.flags & NVM_GET_DEV_INFO_RESP_FLAGS_FW_VER_VALID))
Thomas Bogendoerfer eda5f2
+	    !(nvm_dev_info.flags & NVM_GET_DEV_INFO_RESP_FLAGS_FW_VER_VALID)) {
Thomas Bogendoerfer eda5f2
+		if (!bnxt_get_pkginfo(bp->dev, buf, sizeof(buf)))
Thomas Bogendoerfer eda5f2
+			return bnxt_dl_info_put(bp, req, BNXT_VERSION_STORED,
Thomas Bogendoerfer eda5f2
+						DEVLINK_INFO_VERSION_GENERIC_FW,
Thomas Bogendoerfer eda5f2
+						buf);
Thomas Bogendoerfer eda5f2
 		return 0;
Thomas Bogendoerfer eda5f2
+	}
Thomas Bogendoerfer eda5f2
 
Thomas Bogendoerfer eda5f2
 	buf[0] = 0;
Thomas Bogendoerfer eda5f2
 	strncat(buf, nvm_dev_info.pkg_name, HWRM_FW_VER_STR_LEN);
Thomas Bogendoerfer eda5f2
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
Thomas Bogendoerfer eda5f2
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c
Thomas Bogendoerfer eda5f2
@@ -2832,39 +2832,56 @@ static char *bnxt_parse_pkglog(int desir
Thomas Bogendoerfer eda5f2
 	return retval;
Thomas Bogendoerfer eda5f2
 }
Thomas Bogendoerfer eda5f2
 
Thomas Bogendoerfer eda5f2
-static void bnxt_get_pkgver(struct net_device *dev)
Thomas Bogendoerfer eda5f2
+int bnxt_get_pkginfo(struct net_device *dev, char *ver, int size)
Thomas Bogendoerfer eda5f2
 {
Thomas Bogendoerfer eda5f2
 	struct bnxt *bp = netdev_priv(dev);
Thomas Bogendoerfer eda5f2
 	u16 index = 0;
Thomas Bogendoerfer eda5f2
 	char *pkgver;
Thomas Bogendoerfer eda5f2
 	u32 pkglen;
Thomas Bogendoerfer eda5f2
 	u8 *pkgbuf;
Thomas Bogendoerfer eda5f2
-	int len;
Thomas Bogendoerfer eda5f2
+	int rc;
Thomas Bogendoerfer eda5f2
 
Thomas Bogendoerfer eda5f2
-	if (bnxt_find_nvram_item(dev, BNX_DIR_TYPE_PKG_LOG,
Thomas Bogendoerfer eda5f2
-				 BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
Thomas Bogendoerfer eda5f2
-				 &index, NULL, &pkglen) != 0)
Thomas Bogendoerfer eda5f2
-		return;
Thomas Bogendoerfer eda5f2
+	rc = bnxt_find_nvram_item(dev, BNX_DIR_TYPE_PKG_LOG,
Thomas Bogendoerfer eda5f2
+				  BNX_DIR_ORDINAL_FIRST, BNX_DIR_EXT_NONE,
Thomas Bogendoerfer eda5f2
+				  &index, NULL, &pkglen);
Thomas Bogendoerfer eda5f2
+	if (rc)
Thomas Bogendoerfer eda5f2
+		return rc;
Thomas Bogendoerfer eda5f2
 
Thomas Bogendoerfer eda5f2
 	pkgbuf = kzalloc(pkglen, GFP_KERNEL);
Thomas Bogendoerfer eda5f2
 	if (!pkgbuf) {
Thomas Bogendoerfer eda5f2
 		dev_err(&bp->pdev->dev, "Unable to allocate memory for pkg version, length = %u\n",
Thomas Bogendoerfer eda5f2
 			pkglen);
Thomas Bogendoerfer eda5f2
-		return;
Thomas Bogendoerfer eda5f2
+		return -ENOMEM;
Thomas Bogendoerfer eda5f2
 	}
Thomas Bogendoerfer eda5f2
 
Thomas Bogendoerfer eda5f2
-	if (bnxt_get_nvram_item(dev, index, 0, pkglen, pkgbuf))
Thomas Bogendoerfer eda5f2
+	rc = bnxt_get_nvram_item(dev, index, 0, pkglen, pkgbuf);
Thomas Bogendoerfer eda5f2
+	if (rc)
Thomas Bogendoerfer eda5f2
 		goto err;
Thomas Bogendoerfer eda5f2
 
Thomas Bogendoerfer eda5f2
 	pkgver = bnxt_parse_pkglog(BNX_PKG_LOG_FIELD_IDX_PKG_VERSION, pkgbuf,
Thomas Bogendoerfer eda5f2
 				   pkglen);
Thomas Bogendoerfer eda5f2
-	if (pkgver && *pkgver != 0 && isdigit(*pkgver)) {
Thomas Bogendoerfer eda5f2
+	if (pkgver && *pkgver != 0 && isdigit(*pkgver))
Thomas Bogendoerfer eda5f2
+		strscpy(ver, pkgver, size);
Thomas Bogendoerfer eda5f2
+	else
Thomas Bogendoerfer eda5f2
+		rc = -ENOENT;
Thomas Bogendoerfer eda5f2
+
Thomas Bogendoerfer eda5f2
+err:
Thomas Bogendoerfer eda5f2
+	kfree(pkgbuf);
Thomas Bogendoerfer eda5f2
+
Thomas Bogendoerfer eda5f2
+	return rc;
Thomas Bogendoerfer eda5f2
+}
Thomas Bogendoerfer eda5f2
+
Thomas Bogendoerfer eda5f2
+static void bnxt_get_pkgver(struct net_device *dev)
Thomas Bogendoerfer eda5f2
+{
Thomas Bogendoerfer eda5f2
+	struct bnxt *bp = netdev_priv(dev);
Thomas Bogendoerfer eda5f2
+	char buf[FW_VER_STR_LEN];
Thomas Bogendoerfer eda5f2
+	int len;
Thomas Bogendoerfer eda5f2
+
Thomas Bogendoerfer eda5f2
+	if (!bnxt_get_pkginfo(dev, buf, sizeof(buf))) {
Thomas Bogendoerfer eda5f2
 		len = strlen(bp->fw_ver_str);
Thomas Bogendoerfer eda5f2
 		snprintf(bp->fw_ver_str + len, FW_VER_STR_LEN - len - 1,
Thomas Bogendoerfer eda5f2
-			 "/pkg %s", pkgver);
Thomas Bogendoerfer eda5f2
+			 "/pkg %s", buf);
Thomas Bogendoerfer eda5f2
 	}
Thomas Bogendoerfer eda5f2
-err:
Thomas Bogendoerfer eda5f2
-	kfree(pkgbuf);
Thomas Bogendoerfer eda5f2
 }
Thomas Bogendoerfer eda5f2
 
Thomas Bogendoerfer eda5f2
 static int bnxt_get_eeprom(struct net_device *dev,
Thomas Bogendoerfer eda5f2
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h
Thomas Bogendoerfer eda5f2
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h
Thomas Bogendoerfer eda5f2
@@ -55,6 +55,7 @@ int bnxt_hwrm_firmware_reset(struct net_
Thomas Bogendoerfer eda5f2
 			     u8 self_reset, u8 flags);
Thomas Bogendoerfer eda5f2
 int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware *fw,
Thomas Bogendoerfer eda5f2
 				   u32 install_type);
Thomas Bogendoerfer eda5f2
+int bnxt_get_pkginfo(struct net_device *dev, char *ver, int size);
Thomas Bogendoerfer eda5f2
 void bnxt_ethtool_init(struct bnxt *bp);
Thomas Bogendoerfer eda5f2
 void bnxt_ethtool_free(struct bnxt *bp);
Thomas Bogendoerfer eda5f2