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