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