blob: 4eb6f02ae0223e4702de5071e5da5623f4f5022c [file] [log] [blame]
Harshit Aghera560e6af2025-04-21 20:04:56 +05301/*
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>
Harshit Aghera560e6af2025-04-21 20:04:56 +053013#include <span>
14
15namespace ocp
16{
17namespace accelerator_management
18{
19
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
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