diff --git a/Documentation/networking/devlink/bnxt.rst b/Documentation/networking/devlink/bnxt.rst index 82ef9ec46707e..3dfd84ccb1c7b 100644 --- a/Documentation/networking/devlink/bnxt.rst +++ b/Documentation/networking/devlink/bnxt.rst @@ -51,6 +51,9 @@ The ``bnxt_en`` driver reports the following versions * - Name - Type - Description + * - ``board.id`` + - fixed + - Part number identifying the board design * - ``asic.id`` - fixed - ASIC design identifier @@ -63,12 +66,15 @@ The ``bnxt_en`` driver reports the following versions * - ``fw`` - stored, running - Overall board firmware version - * - ``fw.app`` - - stored, running - - Data path firmware version * - ``fw.mgmt`` - stored, running - - Management firmware version + - NIC hardware resource management firmware version + * - ``fw.mgmt.api`` + - running + - Minimum firmware interface spec version supported between driver and firmware + * - ``fw.nsci`` + - stored, running + - General platform management firmware version * - ``fw.roce`` - stored, running - RoCE management firmware version diff --git a/Documentation/networking/devlink/devlink-info.rst b/Documentation/networking/devlink/devlink-info.rst index e5e5e89f8f7ab..3fe11401b8386 100644 --- a/Documentation/networking/devlink/devlink-info.rst +++ b/Documentation/networking/devlink/devlink-info.rst @@ -157,6 +157,12 @@ Control unit firmware version. This firmware is responsible for house keeping tasks, PHY control etc. but not the packet-by-packet data path operation. +fw.mgmt.api +----------- + +Firmware interface specification version of the software interfaces between +driver and firmware. + fw.app ------ diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c index 1ea8028308943..fead64f1ad90e 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c @@ -7223,7 +7223,7 @@ static int __bnxt_hwrm_ver_get(struct bnxt *bp, bool silent) static int bnxt_hwrm_ver_get(struct bnxt *bp) { struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr; - u32 dev_caps_cfg; + u32 dev_caps_cfg, hwrm_ver; int rc; bp->hwrm_max_req_len = HWRM_MAX_REQ_LEN; @@ -7243,6 +7243,19 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp) resp->hwrm_intf_upd_8b); netdev_warn(bp->dev, "Please update firmware with HWRM interface 1.0.0 or newer.\n"); } + + hwrm_ver = HWRM_VERSION_MAJOR << 16 | HWRM_VERSION_MINOR << 8 | + HWRM_VERSION_UPDATE; + + if (bp->hwrm_spec_code > hwrm_ver) + snprintf(bp->hwrm_ver_supp, FW_VER_STR_LEN, "%d.%d.%d", + HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR, + HWRM_VERSION_UPDATE); + else + snprintf(bp->hwrm_ver_supp, FW_VER_STR_LEN, "%d.%d.%d", + resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b, + resp->hwrm_intf_upd_8b); + snprintf(bp->fw_ver_str, BC_HWRM_STR_LEN, "%d.%d.%d.%d", resp->hwrm_fw_maj_8b, resp->hwrm_fw_min_8b, resp->hwrm_fw_bld_8b, resp->hwrm_fw_rsvd_8b); @@ -11739,6 +11752,63 @@ static int bnxt_init_mac_addr(struct bnxt *bp) return rc; } +#define BNXT_VPD_LEN 512 +static void bnxt_vpd_read_info(struct bnxt *bp) +{ + struct pci_dev *pdev = bp->pdev; + int i, len, pos, ro_size; + ssize_t vpd_size; + u8 *vpd_data; + + vpd_data = kmalloc(BNXT_VPD_LEN, GFP_KERNEL); + if (!vpd_data) + return; + + vpd_size = pci_read_vpd(pdev, 0, BNXT_VPD_LEN, vpd_data); + if (vpd_size <= 0) { + netdev_err(bp->dev, "Unable to read VPD\n"); + goto exit; + } + + i = pci_vpd_find_tag(vpd_data, 0, vpd_size, PCI_VPD_LRDT_RO_DATA); + if (i < 0) { + netdev_err(bp->dev, "VPD READ-Only not found\n"); + goto exit; + } + + ro_size = pci_vpd_lrdt_size(&vpd_data[i]); + i += PCI_VPD_LRDT_TAG_SIZE; + if (i + ro_size > vpd_size) + goto exit; + + pos = pci_vpd_find_info_keyword(vpd_data, i, ro_size, + PCI_VPD_RO_KEYWORD_PARTNO); + if (pos < 0) + goto read_sn; + + len = pci_vpd_info_field_size(&vpd_data[pos]); + pos += PCI_VPD_INFO_FLD_HDR_SIZE; + if (len + pos > vpd_size) + goto read_sn; + + strlcpy(bp->board_partno, &vpd_data[pos], min(len, BNXT_VPD_FLD_LEN)); + +read_sn: + pos = pci_vpd_find_info_keyword(vpd_data, i, ro_size, + PCI_VPD_RO_KEYWORD_SERIALNO); + if (pos < 0) + goto exit; + + len = pci_vpd_info_field_size(&vpd_data[pos]); + pos += PCI_VPD_INFO_FLD_HDR_SIZE; + if (len + pos > vpd_size) + goto exit; + + strlcpy(bp->board_serialno, &vpd_data[pos], min(len, BNXT_VPD_FLD_LEN)); +exit: + kfree(vpd_data); +} + static int bnxt_pcie_dsn_get(struct bnxt *bp, u8 dsn[]) { struct pci_dev *pdev = bp->pdev; @@ -11796,6 +11866,8 @@ static int bnxt_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) dev->ethtool_ops = &bnxt_ethtool_ops; pci_set_drvdata(pdev, dev); + bnxt_vpd_read_info(bp); + rc = bnxt_alloc_hwrm_resources(bp); if (rc) goto init_err_pci_clean; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h index eaf20e371b3c4..f2caa2756f5b2 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h @@ -1500,6 +1500,10 @@ struct bnxt { (chip_num) == CHIP_NUM_58804 || \ (chip_num) == CHIP_NUM_58808) +#define BNXT_VPD_FLD_LEN 32 + char board_partno[BNXT_VPD_FLD_LEN]; + char board_serialno[BNXT_VPD_FLD_LEN]; + struct net_device *dev; struct pci_dev *pdev; @@ -1730,6 +1734,7 @@ struct bnxt { #define BC_HWRM_STR_LEN 21 #define PHY_VER_STR_LEN (FW_VER_STR_LEN - BC_HWRM_STR_LEN) char fw_ver_str[FW_VER_STR_LEN]; + char hwrm_ver_supp[FW_VER_STR_LEN]; __be16 vxlan_port; u8 vxlan_port_cnt; __le16 vxlan_fw_dst_port_id; diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c index d3c93ccee86ad..8e09a52a9c06c 100644 --- a/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c +++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_devlink.c @@ -403,6 +403,14 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req, if (rc) return rc; + if (strlen(bp->board_partno)) { + rc = devlink_info_version_fixed_put(req, + DEVLINK_INFO_VERSION_GENERIC_BOARD_ID, + bp->board_partno); + if (rc) + return rc; + } + sprintf(buf, "%X", bp->chip_num); rc = devlink_info_version_fixed_put(req, DEVLINK_INFO_VERSION_GENERIC_ASIC_ID, buf); @@ -471,13 +479,19 @@ static int bnxt_dl_info_get(struct devlink *dl, struct devlink_info_req *req, ver_resp->roce_fw_bld_8b, ver_resp->roce_fw_rsvd_8b); } rc = devlink_info_version_running_put(req, - DEVLINK_INFO_VERSION_GENERIC_FW_APP, fw_ver); + DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, fw_ver); + if (rc) + return rc; + + rc = devlink_info_version_running_put(req, + DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API, + bp->hwrm_ver_supp); if (rc) return rc; if (!(bp->flags & BNXT_FLAG_CHIP_P5)) { rc = devlink_info_version_running_put(req, - DEVLINK_INFO_VERSION_GENERIC_FW_MGMT, mgmt_ver); + DEVLINK_INFO_VERSION_GENERIC_FW_NCSI, mgmt_ver); if (rc) return rc; diff --git a/include/linux/pci.h b/include/linux/pci.h index fc54b8922e669..a048fba311d2e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -2184,6 +2184,7 @@ int pci_enable_atomic_ops_to_root(struct pci_dev *dev, u32 cap_mask); #define PCI_VPD_INFO_FLD_HDR_SIZE 3 #define PCI_VPD_RO_KEYWORD_PARTNO "PN" +#define PCI_VPD_RO_KEYWORD_SERIALNO "SN" #define PCI_VPD_RO_KEYWORD_MFR_ID "MN" #define PCI_VPD_RO_KEYWORD_VENDOR0 "V0" #define PCI_VPD_RO_KEYWORD_CHKSUM "RV" diff --git a/include/net/devlink.h b/include/net/devlink.h index a1a02cd5890b7..3be50346c69bc 100644 --- a/include/net/devlink.h +++ b/include/net/devlink.h @@ -481,6 +481,8 @@ enum devlink_param_generic_id { #define DEVLINK_INFO_VERSION_GENERIC_FW "fw" /* Control processor FW version */ #define DEVLINK_INFO_VERSION_GENERIC_FW_MGMT "fw.mgmt" +/* FW interface specification version */ +#define DEVLINK_INFO_VERSION_GENERIC_FW_MGMT_API "fw.mgmt.api" /* Data path microcode controlling high-speed packet processing */ #define DEVLINK_INFO_VERSION_GENERIC_FW_APP "fw.app" /* UNDI software version */