blob: 412cd8537af5a8ec71fb8810ee9b078491b246e9 [file] [log] [blame]
Harshit Aghera560e6af2025-04-21 20:04:56 +05301/*
Ed Tanousb5e823f2025-10-09 20:28:42 -04002 * SPDX-FileCopyrightText: Copyright OpenBMC Authors
Harshit Aghera560e6af2025-04-21 20:04:56 +05303 * SPDX-License-Identifier: Apache-2.0
4 */
5
6#include "OcpMctpVdm.hpp"
7
8#include <endian.h>
9
10#include <cerrno>
11#include <cstdint>
Harshit Aghera560e6af2025-04-21 20:04:56 +053012#include <span>
13
14namespace ocp
15{
16namespace accelerator_management
17{
18
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
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