1 /* 2 * SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION & 3 * AFFILIATES. All rights reserved. 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include "OcpMctpVdm.hpp" 8 9 #include <endian.h> 10 11 #include <cerrno> 12 #include <cstdint> 13 #include <cstring> 14 #include <span> 15 16 namespace ocp 17 { 18 namespace accelerator_management 19 { 20 packHeader(uint16_t pciVendorId,const BindingPciVidInfo & hdr,BindingPciVid & msg)21int packHeader(uint16_t pciVendorId, const BindingPciVidInfo& hdr, 22 BindingPciVid& msg) 23 { 24 if (hdr.ocp_accelerator_management_msg_type != 25 static_cast<uint8_t>(MessageType::RESPONSE) && 26 hdr.ocp_accelerator_management_msg_type != 27 static_cast<uint8_t>(MessageType::REQUEST)) 28 { 29 return EINVAL; 30 } 31 32 if (hdr.instance_id > instanceMax) 33 { 34 return EINVAL; 35 } 36 37 msg.instance_id = hdr.instance_id & instanceIdBitMask; 38 39 if (hdr.ocp_accelerator_management_msg_type == 40 static_cast<uint8_t>(MessageType::REQUEST)) 41 { 42 msg.instance_id |= requestBitMask; 43 } 44 else 45 { 46 msg.instance_id &= ~requestBitMask; 47 } 48 49 msg.pci_vendor_id = htobe16(pciVendorId); 50 msg.instance_id &= ~instanceIdReservedBitMask; 51 msg.ocp_version = ocpVersion & ocpVersionBitMask; 52 msg.ocp_version |= (ocpType << ocpTypeBitOffset) & ocpTypeBitMask; 53 msg.ocp_accelerator_management_msg_type = hdr.msg_type; 54 55 return 0; 56 } 57 decodeReasonCodeAndCC(const std::span<const uint8_t> buf,CompletionCode & cc,uint16_t & reasonCode)58int decodeReasonCodeAndCC(const std::span<const uint8_t> buf, 59 CompletionCode& cc, uint16_t& reasonCode) 60 { 61 if (buf.size() < 62 sizeof(ocp::accelerator_management::CommonNonSuccessResponse)) 63 { 64 return EINVAL; 65 } 66 67 // These expression decodes data communicated over the network 68 // The use of reinterpret_cast enables direct memory access to raw byte 69 // buffers without doing unnecessary data copying 70 // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) 71 const auto* response = reinterpret_cast< 72 const ocp::accelerator_management::CommonNonSuccessResponse*>( 73 buf.data()); 74 75 cc = static_cast<CompletionCode>(response->completion_code); 76 if (cc == CompletionCode::SUCCESS) 77 { 78 reasonCode = 0; 79 return 0; 80 } 81 82 // reason code is expected to be present if CC != SUCCESS 83 reasonCode = le16toh(response->reason_code); 84 85 return 0; 86 } 87 } // namespace accelerator_management 88 } // namespace ocp 89