From: Ferruh Yigit Date: Wed, 21 Apr 2021 16:20:57 +0000 (+0100) Subject: drivers/net: fix FW version query X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=d345d6c9575c337189a755c8692be4dd3e1ed708;p=dpdk.git drivers/net: fix FW version query Fixes a few different things: * Remove 'fw_version' NULL checks, it is allowed if the 'fw_size' is zero, 'fw_version' being NULL but 'fw_size' not zero condition checked in ethdev layer * Be sure required buffer size is returned if provided one is not big enough, instead of returning success (0) * Document in doxygen comment the '-EINVAL' is a valid return type * Take into account that 'snprintf' can return negative value * Cast length to 'size_t' to compare it with 'fw_size' Fixes: bb42aa9ffe4e ("net/atlantic: configure device start/stop") Fixes: ff70acdf4299 ("net/axgbe: support reading FW version") Fixes: e2652b0a20a0 ("net/bnxt: support get FW version") Fixes: cf0fab1d2ca5 ("net/dpaa: support firmware version get API") Fixes: 748eccb97cdc ("net/dpaa2: add support for firmware version get") Fixes: b883c0644a24 ("net/e1000: add firmware version get") Fixes: 293430677e9c ("net/enic: add handler to return firmware version") Fixes: 1f5ca0b460cd ("net/hns3: support some device operations") Fixes: bd5b86732bc7 ("net/hns3: modify format for firmware version") Fixes: ed0dfdd0e976 ("net/i40e: add firmware version get") Fixes: e31cb9a36298 ("net/ice: support FW version getting") Fixes: 4f09bc55ac3d ("net/igc: implement device base operations") Fixes: eec10fb0ce6b ("net/ionic: support FW version") Fixes: 8b0b56574269 ("net/ixgbe: add firmware version get") Fixes: 4d9f5b8adc02 ("net/octeontx2: add FW version get operation") Fixes: f97b56f9f12e ("net/qede: support FW version query") Fixes: 83fef46a22b2 ("net/sfc: add callback to retrieve FW version") Fixes: bc84ac0fadef ("net/txgbe: support getting FW version") Fixes: 21913471202f ("ethdev: add firmware version get") Cc: stable@dpdk.org Signed-off-by: Ferruh Yigit Acked-by: Ajit Khaparde Acked-by: Andrew Rybchenko Acked-by: Haiyue Wang Acked-by: Rasesh Mody Acked-by: Jiawen Wu Acked-by: Beilei Xing Acked-by: Hemant Agrawal --- diff --git a/drivers/net/atlantic/atl_ethdev.c b/drivers/net/atlantic/atl_ethdev.c index 473f6209f6..ce7f814f25 100644 --- a/drivers/net/atlantic/atl_ethdev.c +++ b/drivers/net/atlantic/atl_ethdev.c @@ -1073,7 +1073,7 @@ atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) { struct aq_hw_s *hw = ATL_DEV_PRIVATE_TO_HW(dev->data->dev_private); uint32_t fw_ver = 0; - unsigned int ret = 0; + int ret = 0; ret = hw_atl_utils_get_fw_version(hw, &fw_ver); if (ret) @@ -1081,10 +1081,11 @@ atl_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) ret = snprintf(fw_version, fw_size, "%u.%u.%u", fw_ver >> 24, (fw_ver >> 16) & 0xFFU, fw_ver & 0xFFFFU); + if (ret < 0) + return -EINVAL; ret += 1; /* add string null-terminator */ - - if (fw_size < ret) + if (fw_size < (size_t)ret) return ret; return 0; diff --git a/drivers/net/axgbe/axgbe_rxtx.c b/drivers/net/axgbe/axgbe_rxtx.c index e34bb6d448..33f709a6bb 100644 --- a/drivers/net/axgbe/axgbe_rxtx.c +++ b/drivers/net/axgbe/axgbe_rxtx.c @@ -623,9 +623,6 @@ int axgbe_dev_fw_version_get(struct rte_eth_dev *eth_dev, pdata = (struct axgbe_port *)eth_dev->data->dev_private; hw_feat = &pdata->hw_feat; - if (fw_version == NULL) - return -EINVAL; - ret = snprintf(fw_version, fw_size, "%d.%d.%d", AXGMAC_GET_BITS(hw_feat->version, MAC_VR, USERVER), AXGMAC_GET_BITS(hw_feat->version, MAC_VR, DEVID), @@ -634,7 +631,6 @@ int axgbe_dev_fw_version_get(struct rte_eth_dev *eth_dev, return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (size_t)ret) return ret; else diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index f5d2dc8590..dba5b9f94d 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -2794,9 +2794,11 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) ret = snprintf(fw_version, fw_size, "%d.%d.%d.%d", fw_major, fw_minor, fw_updt, fw_rsvd); + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (uint32_t)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/dpaa/dpaa_ethdev.c b/drivers/net/dpaa/dpaa_ethdev.c index 176943a8ea..57ee660c5e 100644 --- a/drivers/net/dpaa/dpaa_ethdev.c +++ b/drivers/net/dpaa/dpaa_ethdev.c @@ -532,9 +532,11 @@ dpaa_fw_version_get(struct rte_eth_dev *dev __rte_unused, ret = snprintf(fw_version, fw_size, "SVR:%x-fman-v%x", svr_ver, fman_ip_rev); - ret += 1; /* add the size of '\0' */ + if (ret < 0) + return -EINVAL; - if (fw_size < (uint32_t)ret) + ret += 1; /* add the size of '\0' */ + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/dpaa2/dpaa2_ethdev.c b/drivers/net/dpaa2/dpaa2_ethdev.c index 9011dcfc12..95e8d9abe8 100644 --- a/drivers/net/dpaa2/dpaa2_ethdev.c +++ b/drivers/net/dpaa2/dpaa2_ethdev.c @@ -226,9 +226,11 @@ dpaa2_fw_version_get(struct rte_eth_dev *dev, mc_ver_info.major, mc_ver_info.minor, mc_ver_info.revision); + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (uint32_t)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/e1000/igb_ethdev.c b/drivers/net/e1000/igb_ethdev.c index 3fdffe3294..10ee0f3341 100644 --- a/drivers/net/e1000/igb_ethdev.c +++ b/drivers/net/e1000/igb_ethdev.c @@ -2159,9 +2159,11 @@ eth_igb_fw_version_get(struct rte_eth_dev *dev, char *fw_version, } break; } + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (u32)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/enic/enic_ethdev.c b/drivers/net/enic/enic_ethdev.c index d91c2cdc8c..e1a393b847 100644 --- a/drivers/net/enic/enic_ethdev.c +++ b/drivers/net/enic/enic_ethdev.c @@ -1050,16 +1050,21 @@ static int enicpmd_dev_fw_version_get(struct rte_eth_dev *eth_dev, int ret; ENICPMD_FUNC_TRACE(); - if (fw_version == NULL || fw_size <= 0) - return -EINVAL; + enic = pmd_priv(eth_dev); ret = vnic_dev_fw_info(enic->vdev, &info); if (ret) return ret; - snprintf(fw_version, fw_size, "%s %s", + ret = snprintf(fw_version, fw_size, "%s %s", info->fw_version, info->fw_build); - fw_version[fw_size - 1] = '\0'; - return 0; + if (ret < 0) + return -EINVAL; + + ret += 1; /* add the size of '\0' */ + if (fw_size < (size_t)ret) + return ret; + else + return 0; } static const struct eth_dev_ops enicpmd_eth_dev_ops = { diff --git a/drivers/net/hns3/hns3_ethdev.c b/drivers/net/hns3/hns3_ethdev.c index 60267e1ec1..bd0699af58 100644 --- a/drivers/net/hns3/hns3_ethdev.c +++ b/drivers/net/hns3/hns3_ethdev.c @@ -2828,8 +2828,11 @@ hns3_fw_version_get(struct rte_eth_dev *eth_dev, char *fw_version, HNS3_FW_VERSION_BYTE1_S), hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M, HNS3_FW_VERSION_BYTE0_S)); + if (ret < 0) + return -EINVAL; + ret += 1; /* add the size of '\0' */ - if (fw_size < (uint32_t)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/hns3/hns3_ethdev_vf.c b/drivers/net/hns3/hns3_ethdev_vf.c index 7a7a6bfa7c..06a26fb9be 100644 --- a/drivers/net/hns3/hns3_ethdev_vf.c +++ b/drivers/net/hns3/hns3_ethdev_vf.c @@ -2181,8 +2181,11 @@ hns3vf_fw_version_get(struct rte_eth_dev *eth_dev, char *fw_version, HNS3_FW_VERSION_BYTE1_S), hns3_get_field(version, HNS3_FW_VERSION_BYTE0_M, HNS3_FW_VERSION_BYTE0_S)); + if (ret < 0) + return -EINVAL; + ret += 1; /* add the size of '\0' */ - if (fw_size < (uint32_t)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index e6206a7e51..66d23d698e 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -3687,9 +3687,11 @@ i40e_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) ((hw->nvm.version >> 4) & 0xff), (hw->nvm.version & 0xf), hw->nvm.eetrack, ver, build, patch); + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (u32)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/ice/ice_ethdev.c b/drivers/net/ice/ice_ethdev.c index da9e85bd7c..c37a2e09ce 100644 --- a/drivers/net/ice/ice_ethdev.c +++ b/drivers/net/ice/ice_ethdev.c @@ -4646,10 +4646,12 @@ ice_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) hw->flash.nvm.minor, hw->flash.nvm.eetrack, ver, build, patch); + if (ret < 0) + return -EINVAL; /* add the size of '\0' */ ret += 1; - if (fw_size < (u32)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/igc/igc_ethdev.c b/drivers/net/igc/igc_ethdev.c index 31c99dca09..b1c58fb3de 100644 --- a/drivers/net/igc/igc_ethdev.c +++ b/drivers/net/igc/igc_ethdev.c @@ -1476,9 +1476,11 @@ eth_igc_fw_version_get(struct rte_eth_dev *dev, char *fw_version, fw.eep_build); } } + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (u32)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/ionic/ionic_ethdev.c b/drivers/net/ionic/ionic_ethdev.c index cffe899c07..5ec474dbf5 100644 --- a/drivers/net/ionic/ionic_ethdev.c +++ b/drivers/net/ionic/ionic_ethdev.c @@ -215,15 +215,18 @@ ionic_dev_fw_version_get(struct rte_eth_dev *eth_dev, { struct ionic_lif *lif = IONIC_ETH_DEV_TO_LIF(eth_dev); struct ionic_adapter *adapter = lif->adapter; + int ret; - if (fw_version == NULL || fw_size <= 0) - return -EINVAL; - - snprintf(fw_version, fw_size, "%s", + ret = snprintf(fw_version, fw_size, "%s", adapter->fw_version); - fw_version[fw_size - 1] = '\0'; + if (ret < 0) + return -EINVAL; - return 0; + ret += 1; /* add the size of '\0' */ + if (fw_size < (size_t)ret) + return ret; + else + return 0; } /* diff --git a/drivers/net/ixgbe/ixgbe_ethdev.c b/drivers/net/ixgbe/ixgbe_ethdev.c index ff65145f55..a5c191fe1b 100644 --- a/drivers/net/ixgbe/ixgbe_ethdev.c +++ b/drivers/net/ixgbe/ixgbe_ethdev.c @@ -3814,9 +3814,11 @@ ixgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) etrack_id = (eeprom_verh << 16) | eeprom_verl; ret = snprintf(fw_version, fw_size, "0x%08x", etrack_id); + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (u32)ret) + if (fw_size < (size_t)ret) return ret; else return 0; diff --git a/drivers/net/octeontx2/otx2_ethdev_ops.c b/drivers/net/octeontx2/otx2_ethdev_ops.c index 6f0cdc5854..5a4501208e 100644 --- a/drivers/net/octeontx2/otx2_ethdev_ops.c +++ b/drivers/net/octeontx2/otx2_ethdev_ops.c @@ -453,7 +453,7 @@ otx2_nix_fw_version_get(struct rte_eth_dev *eth_dev, char *fw_version, rc = strlcpy(fw_version, (char *)dev->mkex_pfl_name, rc); rc += 1; /* Add the size of '\0' */ - if (fw_size < (uint32_t)rc) + if (fw_size < (size_t)rc) return rc; return 0; diff --git a/drivers/net/qede/qede_ethdev.c b/drivers/net/qede/qede_ethdev.c index 057a7b00e2..c2c8de8675 100644 --- a/drivers/net/qede/qede_ethdev.c +++ b/drivers/net/qede/qede_ethdev.c @@ -237,9 +237,6 @@ qede_fw_version_get(struct rte_eth_dev *dev, char *fw_ver, size_t fw_size) static char ver_str[QEDE_PMD_DRV_VER_STR_SIZE]; size_t size; - if (fw_ver == NULL) - return 0; - if (IS_PF(edev)) snprintf(ver_str, QEDE_PMD_DRV_VER_STR_SIZE, "%s", QEDE_PMD_FW_VERSION); diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 52ba7b67b0..c50ecea0b9 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -46,14 +46,6 @@ sfc_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) int ret; int rc; - /* - * Return value of the callback is likely supposed to be - * equal to or greater than 0, nevertheless, if an error - * occurs, it will be desirable to pass it to the caller - */ - if ((fw_version == NULL) || (fw_size == 0)) - return -EINVAL; - rc = efx_nic_get_fw_version(sa->nic, &enfi); if (rc != 0) return -rc; diff --git a/drivers/net/txgbe/txgbe_ethdev.c b/drivers/net/txgbe/txgbe_ethdev.c index 97796f040b..8dbe3da5c2 100644 --- a/drivers/net/txgbe/txgbe_ethdev.c +++ b/drivers/net/txgbe/txgbe_ethdev.c @@ -2582,9 +2582,11 @@ txgbe_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size) hw->phy.get_fw_version(hw, &etrack_id); ret = snprintf(fw_version, fw_size, "0x%08x", etrack_id); + if (ret < 0) + return -EINVAL; ret += 1; /* add the size of '\0' */ - if (fw_size < (u32)ret) + if (fw_size < (size_t)ret) return ret; else return 0;