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