xref: /openbmc/libpldm/include/libpldm/fru.h (revision c6837f00be70b3aac2c654d5e399f57a652452ae)
1 /* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later */
2 #ifndef FRU_H
3 #define FRU_H
4 
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8 
9 #include <libpldm/base.h>
10 
11 #include <asm/byteorder.h>
12 #include <stddef.h>
13 #include <stdint.h>
14 
15 #define PLDM_GET_FRU_RECORD_TABLE_METADATA_REQ_BYTES  0
16 #define PLDM_GET_FRU_RECORD_TABLE_METADATA_RESP_BYTES 19
17 #define PLDM_GET_FRU_RECORD_TABLE_REQ_BYTES	      5
18 #define PLDM_GET_FRU_RECORD_TABLE_MIN_RESP_BYTES      6
19 #define PLDM_GET_FRU_RECORD_BY_OPTION_MIN_RESP_BYTES  6
20 #define PLDM_SET_FRU_RECORD_TABLE_MIN_REQ_BYTES	      5
21 #define PLDM_SET_FRU_RECORD_TABLE_RESP_BYTES	      5
22 
23 #define FRU_TABLE_CHECKSUM_SIZE 4
24 
25 enum pldm_fru_completion_codes {
26 	PLDM_FRU_INVALID_DATA_TRANSFER_HANDLE = 0x80,
27 	PLDM_FRU_INVALID_TRANSFER_FLAG = 0x82,
28 	PLDM_FRU_DATA_INVALID_DATA_INTEGRITY_CHECK = 0x84,
29 	PLDM_FRU_DATA_STRUCTURE_TABLE_UNAVAILABLE = 0x85,
30 };
31 
32 /** @brief PLDM FRU commands
33  */
34 enum pldm_fru_commands {
35 	PLDM_GET_FRU_RECORD_TABLE_METADATA = 0x01,
36 	PLDM_GET_FRU_RECORD_TABLE = 0x02,
37 	PLDM_SET_FRU_RECORD_TABLE = 0x03,
38 	PLDM_GET_FRU_RECORD_BY_OPTION = 0x04
39 };
40 
41 /** @brief FRU record types
42  */
43 enum pldm_fru_record_type {
44 	PLDM_FRU_RECORD_TYPE_GENERAL = 0x01,
45 	PLDM_FRU_RECORD_TYPE_OEM = 0xfe,
46 };
47 
48 /** @brief Encoding type for FRU fields
49  */
50 enum pldm_fru_field_encoding {
51 	PLDM_FRU_ENCODING_UNSPECIFIED = 0x00,
52 	PLDM_FRU_ENCODING_ASCII = 0x01,
53 	PLDM_FRU_ENCODING_UTF8 = 0x02,
54 	PLDM_FRU_ENCODING_UTF16 = 0x03,
55 	PLDM_FRU_ENCODING_UTF16LE = 0x04,
56 	PLDM_FRU_ENCODING_UTF16BE = 0x05,
57 };
58 
59 /** @brief FRU field types
60  */
61 enum pldm_fru_field_type {
62 	PLDM_FRU_FIELD_TYPE_CHASSIS = 0x01,
63 	PLDM_FRU_FIELD_TYPE_MODEL = 0x02,
64 	PLDM_FRU_FIELD_TYPE_PN = 0x03,
65 	PLDM_FRU_FIELD_TYPE_SN = 0x04,
66 	PLDM_FRU_FIELD_TYPE_MANUFAC = 0x05,
67 	PLDM_FRU_FIELD_TYPE_MANUFAC_DATE = 0x06,
68 	PLDM_FRU_FIELD_TYPE_VENDOR = 0x07,
69 	PLDM_FRU_FIELD_TYPE_NAME = 0x08,
70 	PLDM_FRU_FIELD_TYPE_SKU = 0x09,
71 	PLDM_FRU_FIELD_TYPE_VERSION = 0x0a,
72 	PLDM_FRU_FIELD_TYPE_ASSET_TAG = 0x0b,
73 	PLDM_FRU_FIELD_TYPE_DESC = 0x0c,
74 	PLDM_FRU_FIELD_TYPE_EC_LVL = 0x0d,
75 	PLDM_FRU_FIELD_TYPE_OTHER = 0x0e,
76 	PLDM_FRU_FIELD_TYPE_IANA = 0x0f,
77 };
78 
79 /** @struct pldm_get_fru_record_table_metadata_resp
80  *
81  *  Structure representing PLDM get FRU table metadata response.
82  */
83 struct pldm_get_fru_record_table_metadata_resp {
84 	uint8_t completion_code;	//!< completion code
85 	uint8_t fru_data_major_version; //!< The major version of the FRU Record
86 	uint8_t fru_data_minor_version; //!< The minor version of the FRU Record
87 	uint32_t fru_table_maximum_size; //!< The size of the largest FRU Record data
88 	uint32_t fru_table_length; //!< The total length of the FRU Record Table
89 	uint16_t total_record_set_identifiers; //!< The total number of FRU
90 					       //!< Record Data structures
91 	uint16_t total_table_records; //!< The total number of records in the table
92 	uint32_t checksum; //!< The integrity checksum on the FRU Record Table data
93 } __attribute__((packed));
94 
95 /** @struct pldm_get_fru_record_table_req
96  *
97  *  Structure representing PLDM get FRU record table request.
98  */
99 struct pldm_get_fru_record_table_req {
100 	uint32_t data_transfer_handle;
101 	uint8_t transfer_operation_flag;
102 } __attribute__((packed));
103 
104 /** @struct pldm_get_fru_record_table_resp
105  *
106  *  Structure representing PLDM get FRU record table response.
107  */
108 struct pldm_get_fru_record_table_resp {
109 	uint8_t completion_code;
110 	uint32_t next_data_transfer_handle;
111 	uint8_t transfer_flag;
112 	uint8_t fru_record_table_data[1];
113 } __attribute__((packed));
114 
115 struct pldm_get_fru_record_by_option_req {
116 	uint32_t data_transfer_handle;
117 	uint16_t fru_table_handle;
118 	uint16_t record_set_identifier;
119 	uint8_t record_type;
120 	uint8_t field_type;
121 	uint8_t transfer_op_flag;
122 } __attribute__((packed));
123 
124 struct pldm_get_fru_record_by_option_resp {
125 	uint8_t completion_code;
126 	uint32_t next_data_transfer_handle;
127 	uint8_t transfer_flag;
128 	uint8_t fru_structure_data[1];
129 } __attribute__((packed));
130 
131 struct pldm_set_fru_record_table_req {
132 	uint32_t data_transfer_handle;
133 	uint8_t transfer_flag;
134 	uint8_t fru_record_table_data[1];
135 } __attribute__((packed));
136 
137 struct pldm_set_fru_record_table_resp {
138 	uint8_t completion_code;
139 	uint32_t next_data_transfer_handle;
140 } __attribute__((packed));
141 
142 /** @struct pldm_fru_record_tlv
143  *
144  *  Structure representing each FRU field entry (type, length, value)
145  */
146 struct pldm_fru_record_tlv {
147 	uint8_t type;
148 	uint8_t length;
149 	uint8_t value[1];
150 } __attribute__((packed));
151 
152 /** @struct pldm_fru_record_data_format
153  *
154  *  Structure representing the FRU record data format
155  */
156 struct pldm_fru_record_data_format {
157 	uint16_t record_set_id;
158 	uint8_t record_type;
159 	uint8_t num_fru_fields;
160 	uint8_t encoding_type;
161 	struct pldm_fru_record_tlv tlvs[1];
162 } __attribute__((packed));
163 
164 /* Requester */
165 
166 /* GetFRURecordTableMetadata */
167 
168 /** @brief Create a PLDM request message for GetFRURecordTableMetadata
169  *
170  *  @param[in] instance_id - Message's instance id
171  *  @param[in,out] msg - Message will be written to this
172  *  @param[in] payload_length - Length of the request message payload
173  *  @return pldm_completion_codes
174  *  @note  Caller is responsible for memory alloc and dealloc of param
175  *         'msg.payload'
176  */
177 int encode_get_fru_record_table_metadata_req(uint8_t instance_id,
178 					     struct pldm_msg *msg,
179 					     size_t payload_length);
180 
181 /** @brief Decode GetFruRecordTable response data
182  *
183  *  Note:
184  *  * If the return value is not PLDM_SUCCESS, it represents a
185  * transport layer error.
186  *  * If the completion_code value is not PLDM_SUCCESS, it represents a
187  * protocol layer error and all the out-parameters are invalid.
188  *
189  *  @param[in] msg - Response message
190  *  @param[in] payload_length - Length of response message payload
191  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
192  *  @param[out] fru_data_major_version - Major version of the FRU Record
193  *  @param[out] fru_data_minor_version - Minor version of the FRU Record
194  *  @param[out] fru_table_maximum_size - Size of the largest FRU Record data
195  *  @param[out] fru_table_length - Total length of the FRU Record Table
196  *  @param[out] total_Record_Set_Identifiers - Total number of FRU Record Data
197  * structures
198  *  @param[out] total_table_records - Total number of records in the table
199  *  @param[out] checksum - integrity checksum on the FRU Record Table data
200  *  @return pldm_completion_codes
201  */
202 int decode_get_fru_record_table_metadata_resp(
203 	const struct pldm_msg *msg, size_t payload_length,
204 	uint8_t *completion_code, uint8_t *fru_data_major_version,
205 	uint8_t *fru_data_minor_version, uint32_t *fru_table_maximum_size,
206 	uint32_t *fru_table_length, uint16_t *total_record_set_identifiers,
207 	uint16_t *total_table_records, uint32_t *checksum);
208 
209 /* Responder */
210 
211 /* GetFRURecordTableMetadata */
212 
213 /** @brief Create a PLDM response message for GetFRURecordTableMetadata
214  *
215  *  @param[in] instance_id - Message's instance id
216  *  @param[in] completion_code - PLDM completion code
217  *  @param[in] fru_data_major_version - Major version of the FRU Record
218  *  @param[in] fru_data_minor_version - Minor version of the FRU Record
219  *  @param[in] fru_table_maximum_size - Size of the largest FRU Record data
220  *  @param[in] fru_table_length - Total length of the FRU Record Table
221  *  @param[in] total_Record_Set_Identifiers - Total number of FRU Record Data
222  * structures
223  *  @param[in] total_table_records - Total number of records in the table
224  *  @param[in] checksum - integrity checksum on the FRU Record Table data
225  *  @param[in,out] msg - Message will be written to this
226  *  @return pldm_completion_codes
227  *  @note  Caller is responsible for memory alloc and dealloc of param
228  *         'msg.payload'
229  */
230 
231 int encode_get_fru_record_table_metadata_resp(
232 	uint8_t instance_id, uint8_t completion_code,
233 	uint8_t fru_data_major_version, uint8_t fru_data_minor_version,
234 	uint32_t fru_table_maximum_size, uint32_t fru_table_length,
235 	uint16_t total_record_set_identifiers, uint16_t total_table_records,
236 	uint32_t checksum, struct pldm_msg *msg);
237 
238 /* GetFruRecordTable */
239 
240 /** @brief Decode GetFruRecordTable request data
241  *
242  *  @param[in] msg - PLDM request message payload
243  *  @param[in] payload_length - Length of request payload
244  *  @param[out] data_transfer_handle - A handle, used to identify a FRU Record
245  *  Table data transfer
246  *  @param[out] transfer_operation_flag - A flag that indicates whether this is
247  *  the start of the transfer
248  *  @return pldm_completion_codes
249  */
250 int decode_get_fru_record_table_req(const struct pldm_msg *msg,
251 				    size_t payload_length,
252 				    uint32_t *data_transfer_handle,
253 				    uint8_t *transfer_operation_flag);
254 
255 /** @brief Create a PLDM response message for GetFruRecordTable
256  *
257  *  @param[in] instance_id - Message's instance id
258  *  @param[in] completion_code - PLDM completion code
259  *  @param[in] next_data_transfer_handle - A handle that is used to identify the
260  *  next portion of the transfer
261  *  @param[in] transfer_flag - The transfer flag that indicates what part of the
262  *  transfer this response represents
263  *  @param[in,out] msg - Message will be written to this
264  *  @return pldm_completion_codes
265  *  @note  Caller is responsible for memory alloc and dealloc of param 'msg',
266  *         and for appending the FRU table to the msg.
267  */
268 int encode_get_fru_record_table_resp(uint8_t instance_id,
269 				     uint8_t completion_code,
270 				     uint32_t next_data_transfer_handle,
271 				     uint8_t transfer_flag,
272 				     struct pldm_msg *msg);
273 
274 /* GetFRURecordByOption */
275 
276 /** @brief Decode GetFRURecordByOption request data
277  *
278  *  @param[in] msg - PLDM request message payload
279  *  @param[in] payload_length - Length of request payload
280  *  @param[out] data_transfer_handle - A handle, used to identify a FRU Record
281  *              Table data transfer
282  *  @param[out] fru_table_handle - A handle, used to identify a FRU DATA
283  *              records
284  *  @param[out] record_set_identifier - FRU record set identifier
285  *  @param[out] record_type - FRU record type
286  *  @param[out] field_type - FRU field type
287  *  @param[out] transfer_op_flag - A flag that indicates whether this is
288  *              the start of the transfer
289  *  @return pldm_completion_codes
290  */
291 int decode_get_fru_record_by_option_req(
292 	const struct pldm_msg *msg, size_t payload_length,
293 	uint32_t *data_transfer_handle, uint16_t *fru_table_handle,
294 	uint16_t *record_set_identifier, uint8_t *record_type,
295 	uint8_t *field_type, uint8_t *transfer_op_flag);
296 
297 /** @brief Encode GetFRURecordByOption response data
298  *
299  *  @param[in] instance_id - Message's instance id
300  *  @param[in] completion_code - PLDM completion code
301  *  @param[in] next_data_transfer_handle - A handle that is used to identify the
302  *             next portion of the transfer
303  *  @param[in] transfer_flag - The transfer flag that indicates what part of the
304  *             transfer this response represents
305  *  @param[in] fru_structure_data - FRU Structure Data
306  *  @param[in] data_size - Size of FRU Structure Data
307  *  @param[in,out] msg - Message will be written to this
308  *  @return pldm_completion_codes
309  *  @note  Caller is responsible for memory alloc and dealloc of param 'msg',
310  *         and for appending the FRU table to the msg.
311  */
312 int encode_get_fru_record_by_option_resp(uint8_t instance_id,
313 					 uint8_t completion_code,
314 					 uint32_t next_data_transfer_handle,
315 					 uint8_t transfer_flag,
316 					 const void *fru_structure_data,
317 					 size_t data_size, struct pldm_msg *msg,
318 					 size_t payload_length);
319 
320 /* Requester */
321 
322 /* GetFruRecordTable */
323 
324 /** @brief Create a PLDM request message for GetFruRecordTable
325  *
326  *  @param[in] instance_id - Message's instance id
327  *  @param[in] data_transfer_handle - A handle, used to identify a FRU Record
328  *  Table data transfer
329  *  @param[in] transfer_operation_flag - A flag that indicates whether this is
330  *  the start of the transfer
331  *  @param[in,out] msg - Message will be written to this
332  *  @param[in] payload_length - Length of request message payload
333  *  @return pldm_completion_codes
334  *  @note  Caller is responsible for memory alloc and dealloc of param
335  *         'msg.payload'
336  */
337 
338 int encode_get_fru_record_table_req(uint8_t instance_id,
339 				    uint32_t data_transfer_handle,
340 				    uint8_t transfer_operation_flag,
341 				    struct pldm_msg *msg,
342 				    size_t payload_length);
343 
344 /** @brief Decode GetFruRecordTable response data
345  *
346  *  @param[in] msg - Response message
347  *  @param[in] payload_length - Length of response message payload
348  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
349  *  @param[out] next_data_transfer_handle - A handle used to identify the next
350  *  portion of the transfer
351  *  @param[out] transfer_flag - The transfer flag that indicates what part of
352  * the transfer this response represents
353  *  @param[out] fru_record_table_data - This data is a portion of the overall
354  * FRU Record Table
355  *  @param[out] fru_record_table_length - Length of the FRU record table data
356  *  @return pldm_completion_codes
357  */
358 
359 int decode_get_fru_record_table_resp(const struct pldm_msg *msg,
360 				     size_t payload_length,
361 				     uint8_t *completion_code,
362 				     uint32_t *next_data_transfer_handle,
363 				     uint8_t *transfer_flag,
364 				     uint8_t *fru_record_table_data,
365 				     size_t *fru_record_table_length);
366 
367 /** @brief Decode GetFruRecordTable response data, ensuring that the fru
368  *         record table section is small enough to fit in the provided buffer.
369  *
370  *  @param[in] msg - Response message
371  *  @param[in] payload_length - Length of response message payload
372  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
373  *  @param[out] next_data_transfer_handle - A handle used to identify the next
374  *  portion of the transfer
375  *  @param[out] transfer_flag - The transfer flag that indicates what part of
376  * the transfer this response represents
377  *  @param[out] fru_record_table_data - This data is a portion of the overall
378  * FRU Record Table
379  *  @param[out] fru_record_table_length - Length of the FRU record table data
380  *  @param[in] max_fru_record_table_length - Maximum length of the FRU record
381  * table data. If the response contains more data than this,
382  * return PLDM_ERROR_INVALID_LENGTH.
383  *  @return pldm_completion_codes
384  */
385 
386 int decode_get_fru_record_table_resp_safe(
387 	const struct pldm_msg *msg, size_t payload_length,
388 	uint8_t *completion_code, uint32_t *next_data_transfer_handle,
389 	uint8_t *transfer_flag, uint8_t *fru_record_table_data,
390 	size_t *fru_record_table_length, size_t max_fru_record_table_length);
391 
392 /** @brief Encode the FRU record in the FRU table
393  *
394  *  @param[in/out] fru_table - Pointer to the FRU table
395  *  @param[in] total_size - The size of the table,including the size of FRU
396  *                          record to be added to the table.
397  *  @param[in/out] curr_size - The size of the table, excluding the size of FRU
398  *                          record to be added to the table.
399  *  @param[in] record_set_id - FRU record set identifier
400  *  @param[in] record_type - FRU record type
401  *  @param[in] num_frus - Number of FRU fields
402  *  @param[in] encoding - Encoding type for FRU fields
403  *  @param[in] tlvs - Pointer to the buffer with all the FRU fields
404  *  @param[in] tlvs_size - Size of the  buffer with all the FRU fields
405  *
406  *  @return pldm_completion_codes
407  */
408 int encode_fru_record(uint8_t *fru_table, size_t total_size, size_t *curr_size,
409 		      uint16_t record_set_id, uint8_t record_type,
410 		      uint8_t num_frus, uint8_t encoding, uint8_t *tlvs,
411 		      size_t tlvs_size);
412 
413 /* GetFRURecordByOption */
414 
415 /** @brief Create a PLDM request message for GetFRURecordByOption
416  *
417  *  @param[in] instance_id - Message's instance id
418  *  @param[in] data_transfer_handle - A handle, used to identify a FRU Record
419  *             Table data transfer
420  *  @param[in] fru_table_handle - A handle, used to identify a FRU DATA records
421  *  @param[in] record_set_identifier - FRU record set identifier
422  *  @param[in] record_type - FRU record type
423  *  @param[in] field_type - FRU field type
424  *  @param[in] transfer_op_flag - A flag that indicates whether this is
425  *             the start of the transfer
426  *  @param[in,out] msg - Message will be written to this
427  *  @param[in] payload_length - Length of request message payload
428  *  @return pldm_completion_codes
429  *  @note  Caller is responsible for memory alloc and dealloc of param
430  *         'msg.payload'
431  */
432 int encode_get_fru_record_by_option_req(
433 	uint8_t instance_id, uint32_t data_transfer_handle,
434 	uint16_t fru_table_handle, uint16_t record_set_identifier,
435 	uint8_t record_type, uint8_t field_type, uint8_t transfer_op_flag,
436 	struct pldm_msg *msg, size_t payload_length);
437 
438 /** @brief Decode GetFRURecordByOption response data
439  *
440  *  @param[in] msg - Response message
441  *  @param[in] payload_length - Length of response message payload
442  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
443  *  @param[out] next_data_transfer_handle - A handle used to identify the next
444  *              portion of the transfer
445  *  @param[out] transfer_flag - The transfer flag that indicates what part of
446  *              the transfer this response represents
447  *  @param[out] fru_structure_data - FRU Structure Data
448  *  @return pldm_completion_codes
449  */
450 int decode_get_fru_record_by_option_resp(
451 	const struct pldm_msg *msg, size_t payload_length,
452 	uint8_t *completion_code, uint32_t *next_transfer_handle,
453 	uint8_t *transfer_flag, struct variable_field *fru_structure_data);
454 
455 /** @brief Get FRU Record Table By Option or return an error
456  *  @param[in] table - The source fru record table
457  *  @param[in] table_size - Size of the source fru record table
458  *  @param[out] record_table - Fru table fetched based on the input option
459  *  @param[in/out] record_size - Size of the table fetched by fru record option
460  *  @param[in] rsi - FRU record set identifier
461  *  @param[in] rt - FRU record type
462  *  @param[in] ft - FRU field type
463  *
464  *  @return PLDM_SUCCESS if no error occurs. PLDM_ERROR_INVALID_LENGTH if record_size lacks capacity
465  *  	    to encode the relevant records.
466  */
467 int get_fru_record_by_option(const uint8_t *table, size_t table_size,
468 			     uint8_t *record_table, size_t *record_size,
469 			     uint16_t rsi, uint8_t rt, uint8_t ft);
470 
471 /* SetFruRecordTable */
472 
473 /** @brief Decode SetFruRecordTable request data
474  *
475  *  @param[in] msg - PLDM request message payload
476  *  @param[in] payload_length - Length of request payload
477  *  @param[out] data_transfer_handle - A handle used to identify a FRU Record
478  *                                     table data transfer
479  *  @param[out] transfer_flag - Flag to indicate what part of the transfer
480  *                              this request represents
481  *  @param[out] fru_table_data - Struct variable_field, contains data specific
482  *                               to the fru record table and the length of table
483  *                               data
484  *  @return pldm_completion_codes
485  */
486 int decode_set_fru_record_table_req(const struct pldm_msg *msg,
487 				    size_t payload_length,
488 				    uint32_t *data_transfer_handle,
489 				    uint8_t *transfer_flag,
490 				    struct variable_field *fru_table_data);
491 
492 /** @brief Create a PLDM response message for SetFruRecordTable
493  *
494  *  @param[in] instance_id - Message's instance id
495  *  @param[in] completion_code - PLDM completion code
496  *  @param[in] next_transfer_handle - handle to identify the next portion of the
497  *                                    transfer
498  *  @param[in] payload_length - Length of payload message
499  *  @param[out] msg - Argument to capture the Message
500  */
501 int encode_set_fru_record_table_resp(uint8_t instance_id,
502 				     uint8_t completion_code,
503 				     uint32_t next_data_transfer_handle,
504 				     size_t payload_length,
505 				     struct pldm_msg *msg);
506 
507 #ifdef __cplusplus
508 }
509 #endif
510 
511 #endif
512