diff mbox series

[V7,17/21] core/pldm: Update "bmc-firmware-version" device-tree field

Message ID 20230511162446.10457-18-clombard@linux.ibm.com
State Superseded
Headers show
Series Implement MCTP and PLDM features | expand

Commit Message

Christophe Lombard May 11, 2023, 4:24 p.m. UTC
Use the GetFruRecordByOptionReq command to retrieve the bmc information
with: "FRU Field Type": Version
      "FRU Record Set Identifier": 1,
      "FRU Record Type": "General(1)"
and update the "bmc-firmware-version" device-tree field.

Reviewed-by: Abhishek Singh Tomar <abhishek@linux.ibm.com>
Signed-off-by: Christophe Lombard <clombard@linux.ibm.com>
---
 core/pldm/pldm-fru-requests.c | 84 +++++++++++++++++++++++++++++++++++
 core/pldm/pldm.h              |  1 +
 include/pldm.h                |  5 +++
 3 files changed, 90 insertions(+)
diff mbox series

Patch

diff --git a/core/pldm/pldm-fru-requests.c b/core/pldm/pldm-fru-requests.c
index ae1d9fac..aa4ce662 100644
--- a/core/pldm/pldm-fru-requests.c
+++ b/core/pldm/pldm-fru-requests.c
@@ -15,6 +15,7 @@  static void *fru_record_table;
 static size_t fru_record_length;
 
 static bool fru_ready;
+static char *bmc_version = NULL;
 
 static void fru_init_complete(bool success)
 {
@@ -33,6 +34,22 @@  static void fru_init_complete(bool success)
 	fru_ready = true;
 }
 
+int pldm_fru_get_bmc_version(void *bv, int len)
+{
+	if (bv == NULL)
+		return OPAL_PARAMETER;
+
+	if (bmc_version == NULL)
+		return OPAL_PARAMETER;
+
+	if ((len + 1) > strlen(bmc_version))
+		return OPAL_PARAMETER;
+
+	memcpy(bv, bmc_version, strlen(bmc_version) + 1);
+
+	return OPAL_SUCCESS;
+}
+
 static int get_fru_record_table_req(void **record_table_data,
 				    size_t *record_table_length)
 {
@@ -126,6 +143,73 @@  out:
 	return rc;
 }
 
+int pldm_fru_dt_add_bmc_version(void)
+{
+	struct pldm_fru_record_data_format *data;
+	struct pldm_fru_record_tlv *tlv;
+	struct dt_node *dt_fw_version;
+	uint8_t *record_table;
+	int rc = OPAL_SUCCESS;
+	size_t record_size;
+
+	if (!fru_ready)
+		return OPAL_HARDWARE;
+
+	if (!fru_record_table)
+		return OPAL_HARDWARE;
+
+	dt_fw_version = dt_find_by_name(dt_root, "ibm,firmware-versions");
+	assert(dt_fw_version);
+
+	/* retrieve the bmc information with
+	 * "FRU Record Set Identifier": 1,
+	 * "FRU Record Type": "General(1)"
+	 * "FRU Field Type": Version
+	 *
+	 * we can not know size of the record table got by options
+	 * in advance, but it must be less than the source table. So
+	 * it's safe to use sizeof the source table.
+	 */
+	record_table = zalloc(fru_record_length);
+	if (!record_table)
+		return OPAL_NO_MEM;
+
+	record_size = fru_record_length;
+	get_fru_record_by_option(
+			fru_record_table,
+			fru_record_length - PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES,
+			record_table,
+			&record_size,
+			1,
+			PLDM_FRU_RECORD_TYPE_GENERAL,
+			PLDM_FRU_FIELD_TYPE_VERSION);
+
+	if (record_size == 0) {
+		prlog(PR_ERR, "%s - no FRU type version found\n", __func__);
+		rc = OPAL_PARAMETER;
+		goto out;
+	}
+
+	/* get tlv value */
+	data = (struct pldm_fru_record_data_format *)record_table;
+	tlv = (struct pldm_fru_record_tlv *)data->tlvs;
+	prlog(PR_DEBUG, "%s - value: %s\n", __func__, tlv->value);
+
+	dt_add_property_string(dt_fw_version, "bmc-firmware-version",
+			       tlv->value);
+
+	/* store the bmc version */
+	bmc_version = zalloc(tlv->length + 1);
+	if (!bmc_version)
+		rc = OPAL_NO_MEM;
+	else
+		memcpy(bmc_version, tlv->value, tlv->length);
+
+out:
+	free(record_table);
+	return rc;
+}
+
 int pldm_fru_init(void)
 {
 	int rc;
diff --git a/core/pldm/pldm.h b/core/pldm/pldm.h
index 8f52fc62..1e01205a 100644
--- a/core/pldm/pldm.h
+++ b/core/pldm/pldm.h
@@ -52,6 +52,7 @@  int pldm_responder_handle_request(struct pldm_rx_data *rx);
 int pldm_responder_init(void);
 
 /* Requester support */
+int pldm_fru_get_bmc_version(void *bv, int len);
 int pldm_fru_init(void);
 
 int pldm_bios_find_lid_by_attr_name(const char *name, char **lid);
diff --git a/include/pldm.h b/include/pldm.h
index 55a4e149..3c23dc97 100644
--- a/include/pldm.h
+++ b/include/pldm.h
@@ -31,4 +31,9 @@  int pldm_platform_power_off(void);
  */
 int pldm_platform_restart(void);
 
+/**
+ * Update the firmware version device-tree field
+ */
+int pldm_fru_dt_add_bmc_version(void);
+
 #endif /* __PLDM_H__ */