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