xref: /openbmc/dbus-sensors/src/nvidia-gpu/OcpMctpVdm.cpp (revision 0d2f96f1e95a6a37f00a3c458c8562d6af92e4a4)
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)20 int 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)57 int 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