xref: /openbmc/libpldm/include/libpldm/fru.h (revision 9c766792)
1 #ifndef FRU_H
2 #define FRU_H
3 
4 #ifdef __cplusplus
5 extern "C" {
6 #endif
7 
8 #include <asm/byteorder.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 
12 #include "base.h"
13 #include "utils.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
88 	    fru_table_maximum_size; //!< The size of the largest FRU Record data
89 	uint32_t fru_table_length; //!< The total length of the FRU Record Table
90 	uint16_t total_record_set_identifiers; //!< The total number of FRU
91 					       //!< Record Data structures
92 	uint16_t
93 	    total_table_records; //!< The total number of records in the table
94 	uint32_t
95 	    checksum; //!< The integrity checksum on the FRU Record Table data
96 } __attribute__((packed));
97 
98 /** @struct pldm_get_fru_record_table_req
99  *
100  *  Structure representing PLDM get FRU record table request.
101  */
102 struct pldm_get_fru_record_table_req {
103 	uint32_t data_transfer_handle;
104 	uint8_t transfer_operation_flag;
105 } __attribute__((packed));
106 
107 /** @struct pldm_get_fru_record_table_resp
108  *
109  *  Structure representing PLDM get FRU record table response.
110  */
111 struct pldm_get_fru_record_table_resp {
112 	uint8_t completion_code;
113 	uint32_t next_data_transfer_handle;
114 	uint8_t transfer_flag;
115 	uint8_t fru_record_table_data[1];
116 } __attribute__((packed));
117 
118 struct pldm_get_fru_record_by_option_req {
119 	uint32_t data_transfer_handle;
120 	uint16_t fru_table_handle;
121 	uint16_t record_set_identifier;
122 	uint8_t record_type;
123 	uint8_t field_type;
124 	uint8_t transfer_op_flag;
125 } __attribute__((packed));
126 
127 struct pldm_get_fru_record_by_option_resp {
128 	uint8_t completion_code;
129 	uint32_t next_data_transfer_handle;
130 	uint8_t transfer_flag;
131 	uint8_t fru_structure_data[1];
132 } __attribute__((packed));
133 
134 struct pldm_set_fru_record_table_req {
135 	uint32_t data_transfer_handle;
136 	uint8_t transfer_flag;
137 	uint8_t fru_record_table_data[1];
138 } __attribute__((packed));
139 
140 struct pldm_set_fru_record_table_resp {
141 	uint8_t completion_code;
142 	uint32_t next_data_transfer_handle;
143 } __attribute__((packed));
144 
145 /** @struct pldm_fru_record_tlv
146  *
147  *  Structure representing each FRU field entry (type, length, value)
148  */
149 struct pldm_fru_record_tlv {
150 	uint8_t type;
151 	uint8_t length;
152 	uint8_t value[1];
153 } __attribute__((packed));
154 
155 /** @struct pldm_fru_record_data_format
156  *
157  *  Structure representing the FRU record data format
158  */
159 struct pldm_fru_record_data_format {
160 	uint16_t record_set_id;
161 	uint8_t record_type;
162 	uint8_t num_fru_fields;
163 	uint8_t encoding_type;
164 	struct pldm_fru_record_tlv tlvs[1];
165 } __attribute__((packed));
166 
167 /* Requester */
168 
169 /* GetFRURecordTableMetadata */
170 
171 /** @brief Create a PLDM request message for GetFRURecordTableMetadata
172  *
173  *  @param[in] instance_id - Message's instance id
174  *  @param[in,out] msg - Message will be written to this
175  *  @param[in] payload_length - Length of the request message payload
176  *  @return pldm_completion_codes
177  *  @note  Caller is responsible for memory alloc and dealloc of param
178  *         'msg.payload'
179  */
180 int encode_get_fru_record_table_metadata_req(uint8_t instance_id,
181 					     struct pldm_msg *msg,
182 					     size_t payload_length);
183 
184 /** @brief Decode GetFruRecordTable response data
185  *
186  *  Note:
187  *  * If the return value is not PLDM_SUCCESS, it represents a
188  * transport layer error.
189  *  * If the completion_code value is not PLDM_SUCCESS, it represents a
190  * protocol layer error and all the out-parameters are invalid.
191  *
192  *  @param[in] msg - Response message
193  *  @param[in] payload_length - Length of response message payload
194  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
195  *  @param[out] fru_data_major_version - Major version of the FRU Record
196  *  @param[out] fru_data_minor_version - Minor version of the FRU Record
197  *  @param[out] fru_table_maximum_size - Size of the largest FRU Record data
198  *  @param[out] fru_table_length - Total length of the FRU Record Table
199  *  @param[out] total_Record_Set_Identifiers - Total number of FRU Record Data
200  * structures
201  *  @param[out] total_table_records - Total number of records in the table
202  *  @param[out] checksum - integrity checksum on the FRU Record Table data
203  *  @return pldm_completion_codes
204  */
205 int decode_get_fru_record_table_metadata_resp(
206     const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
207     uint8_t *fru_data_major_version, uint8_t *fru_data_minor_version,
208     uint32_t *fru_table_maximum_size, uint32_t *fru_table_length,
209     uint16_t *total_record_set_identifiers, uint16_t *total_table_records,
210     uint32_t *checksum);
211 
212 /* Responder */
213 
214 /* GetFRURecordTableMetadata */
215 
216 /** @brief Create a PLDM response message for GetFRURecordTableMetadata
217  *
218  *  @param[in] instance_id - Message's instance id
219  *  @param[in] completion_code - PLDM completion code
220  *  @param[in] fru_data_major_version - Major version of the FRU Record
221  *  @param[in] fru_data_minor_version - Minor version of the FRU Record
222  *  @param[in] fru_table_maximum_size - Size of the largest FRU Record data
223  *  @param[in] fru_table_length - Total length of the FRU Record Table
224  *  @param[in] total_Record_Set_Identifiers - Total number of FRU Record Data
225  * structures
226  *  @param[in] total_table_records - Total number of records in the table
227  *  @param[in] checksum - integrity checksum on the FRU Record Table data
228  *  @param[in,out] msg - Message will be written to this
229  *  @return pldm_completion_codes
230  *  @note  Caller is responsible for memory alloc and dealloc of param
231  *         'msg.payload'
232  */
233 
234 int encode_get_fru_record_table_metadata_resp(
235     uint8_t instance_id, uint8_t completion_code,
236     uint8_t fru_data_major_version, uint8_t fru_data_minor_version,
237     uint32_t fru_table_maximum_size, uint32_t fru_table_length,
238     uint16_t total_record_set_identifiers, uint16_t total_table_records,
239     uint32_t checksum, struct pldm_msg *msg);
240 
241 /* GetFruRecordTable */
242 
243 /** @brief Decode GetFruRecordTable request data
244  *
245  *  @param[in] msg - PLDM request message payload
246  *  @param[in] payload_length - Length of request payload
247  *  @param[out] data_transfer_handle - A handle, used to identify a FRU Record
248  *  Table data transfer
249  *  @param[out] transfer_operation_flag - A flag that indicates whether this is
250  *  the start of the transfer
251  *  @return pldm_completion_codes
252  */
253 int decode_get_fru_record_table_req(const struct pldm_msg *msg,
254 				    size_t payload_length,
255 				    uint32_t *data_transfer_handle,
256 				    uint8_t *transfer_operation_flag);
257 
258 /** @brief Create a PLDM response message for GetFruRecordTable
259  *
260  *  @param[in] instance_id - Message's instance id
261  *  @param[in] completion_code - PLDM completion code
262  *  @param[in] next_data_transfer_handle - A handle that is used to identify the
263  *  next portion of the transfer
264  *  @param[in] transfer_flag - The transfer flag that indicates what part of the
265  *  transfer this response represents
266  *  @param[in,out] msg - Message will be written to this
267  *  @return pldm_completion_codes
268  *  @note  Caller is responsible for memory alloc and dealloc of param 'msg',
269  *         and for appending the FRU table to the msg.
270  */
271 int encode_get_fru_record_table_resp(uint8_t instance_id,
272 				     uint8_t completion_code,
273 				     uint32_t next_data_transfer_handle,
274 				     uint8_t transfer_flag,
275 				     struct pldm_msg *msg);
276 
277 /* GetFRURecordByOption */
278 
279 /** @brief Decode GetFRURecordByOption request data
280  *
281  *  @param[in] msg - PLDM request message payload
282  *  @param[in] payload_length - Length of request payload
283  *  @param[out] data_transfer_handle - A handle, used to identify a FRU Record
284  *              Table data transfer
285  *  @param[out] fru_table_handle - A handle, used to identify a FRU DATA
286  *              records
287  *  @param[out] record_set_identifier - FRU record set identifier
288  *  @param[out] record_type - FRU record type
289  *  @param[out] field_type - FRU field type
290  *  @param[out] transfer_op_flag - A flag that indicates whether this is
291  *              the start of the transfer
292  *  @return pldm_completion_codes
293  */
294 int decode_get_fru_record_by_option_req(
295     const struct pldm_msg *msg, size_t payload_length,
296     uint32_t *data_transfer_handle, uint16_t *fru_table_handle,
297     uint16_t *record_set_identifier, uint8_t *record_type, uint8_t *field_type,
298     uint8_t *transfer_op_flag);
299 
300 /** @brief Encode GetFRURecordByOption response data
301  *
302  *  @param[in] instance_id - Message's instance id
303  *  @param[in] completion_code - PLDM completion code
304  *  @param[in] next_data_transfer_handle - A handle that is used to identify the
305  *             next portion of the transfer
306  *  @param[in] transfer_flag - The transfer flag that indicates what part of the
307  *             transfer this response represents
308  *  @param[in] fru_structure_data - FRU Structure Data
309  *  @param[in] data_size - Size of FRU Structrue Data
310  *  @param[in,out] msg - Message will be written to this
311  *  @return pldm_completion_codes
312  *  @note  Caller is responsible for memory alloc and dealloc of param 'msg',
313  *         and for appending the FRU table to the msg.
314  */
315 int encode_get_fru_record_by_option_resp(uint8_t instance_id,
316 					 uint8_t completion_code,
317 					 uint32_t next_data_transfer_handle,
318 					 uint8_t transfer_flag,
319 					 const void *fru_structure_data,
320 					 size_t data_size, struct pldm_msg *msg,
321 					 size_t payload_length);
322 
323 /* Requester */
324 
325 /* GetFruRecordTable */
326 
327 /** @brief Create a PLDM request message for GetFruRecordTable
328  *
329  *  @param[in] instance_id - Message's instance id
330  *  @param[in] data_transfer_handle - A handle, used to identify a FRU Record
331  *  Table data transfer
332  *  @param[in] transfer_operation_flag - A flag that indicates whether this is
333  *  the start of the transfer
334  *  @param[in,out] msg - Message will be written to this
335  *  @param[in] payload_length - Length of request message payload
336  *  @return pldm_completion_codes
337  *  @note  Caller is responsible for memory alloc and dealloc of param
338  *         'msg.payload'
339  */
340 
341 int encode_get_fru_record_table_req(uint8_t instance_id,
342 				    uint32_t data_transfer_handle,
343 				    uint8_t transfer_operation_flag,
344 				    struct pldm_msg *msg,
345 				    size_t payload_length);
346 
347 /** @brief Decode GetFruRecordTable response data
348  *
349  *  @param[in] msg - Response message
350  *  @param[in] payload_length - Length of response message payload
351  *  @param[out] completion_code - Pointer to response msg's PLDM completion code
352  *  @param[out] next_data_transfer_handle - A handle used to identify the next
353  *  portion of the transfer
354  *  @param[out] transfer_flag - The transfer flag that indicates what part of
355  * the transfer this response represents
356  *  @param[out] fru_record_table_data - This data is a portion of the overall
357  * FRU Record Table
358  *  @param[out] fru_record_table_length - Length of the FRU record table data
359  *  @return pldm_completion_codes
360  */
361 
362 int decode_get_fru_record_table_resp(
363     const struct pldm_msg *msg, size_t payload_length, uint8_t *completion_code,
364     uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
365     uint8_t *fru_record_table_data, 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, uint8_t *completion_code,
388     uint32_t *next_data_transfer_handle, uint8_t *transfer_flag,
389     uint8_t *fru_record_table_data, size_t *fru_record_table_length,
390     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, uint8_t *completion_code,
452     uint32_t *next_transfer_handle, uint8_t *transfer_flag,
453     struct variable_field *fru_structure_data);
454 
455 /** @brief Get FRU Record Table By Option
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 void get_fru_record_by_option(const uint8_t *table, size_t table_size,
465 			      uint8_t *record_table, size_t *record_size,
466 			      uint16_t rsi, uint8_t rt, uint8_t ft);
467 /* SetFruRecordTable */
468 
469 /** @brief Decode SetFruRecordTable request data
470  *
471  *  @param[in] msg - PLDM request message payload
472  *  @param[in] payload_length - Length of request payload
473  *  @param[out] data_transfer_handle - A handle used to identify a FRU Record
474  *                                     table data transfer
475  *  @param[out] transfer_flag - Flag to indicate what part of the transfer
476  *                              this request represents
477  *  @param[out] fru_table_data - Struct variable_field, contains data specific
478  *                               to the fru record table and the length of table
479  *                               data
480  *  @return pldm_completion_codes
481  */
482 int decode_set_fru_record_table_req(const struct pldm_msg *msg,
483 				    size_t payload_length,
484 				    uint32_t *data_transfer_handle,
485 				    uint8_t *transfer_flag,
486 				    struct variable_field *fru_table_data);
487 
488 /** @brief Create a PLDM response message for SetFruRecordTable
489  *
490  *  @param[in] instance_id - Message's instance id
491  *  @param[in] completion_code - PLDM completion code
492  *  @param[in] next_transfer_handle - handle to identify the next portion of the
493  *                                    transfer
494  *  @param[in] payload_length - Length of payload message
495  *  @param[out] msg - Argument to capture the Message
496  */
497 int encode_set_fru_record_table_resp(uint8_t instance_id,
498 				     uint8_t completion_code,
499 				     uint32_t next_data_transfer_handle,
500 				     size_t payload_length,
501 				     struct pldm_msg *msg);
502 
503 #ifdef __cplusplus
504 }
505 #endif
506 
507 #endif
508