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