blob: 9eb17c4f996fb9d0e1d2e01987b78a374397191b [file] [log] [blame]
/*
* SPDX-FileCopyrightText: Copyright (c) 2024-2025 NVIDIA CORPORATION &
* AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0
*/
#include <GpuMctpVdm.hpp>
#include <MctpRequester.hpp>
#include <OcpMctpVdm.hpp>
#include <phosphor-logging/lg2.hpp>
#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <vector>
void readThermalParameter(uint8_t eid, uint8_t id,
mctp::MctpRequester& mctpRequester,
const std::function<void(uint8_t, int32_t)>& callback)
{
std::vector<uint8_t> reqMsg(
sizeof(ocp::accelerator_management::BindingPciVid) +
sizeof(gpu::ReadThermalParametersRequest));
auto* msg = new (reqMsg.data()) ocp::accelerator_management::Message;
auto rc = gpu::encodeReadThermalParametersRequest(0, id, *msg);
if (rc != ocp::accelerator_management::CompletionCode::SUCCESS)
{
lg2::error("encodeReadThermalParametersRequest failed, rc={RC}", "RC",
static_cast<int>(rc));
callback(-1, 0);
return;
}
mctpRequester.sendRecvMsg(
eid, reqMsg,
[callback](int sendRecvMsgResult, std::vector<uint8_t> respMsg) {
if (sendRecvMsgResult != 0)
{
lg2::error("MctpRequester::sendRecvMsg() failed, rc={RC}", "RC",
sendRecvMsgResult);
callback(-2, 0);
return;
}
if (respMsg.empty())
{
lg2::error("MctpRequester::sendRecvMsg() failed, respMsgLen=0");
callback(-3, 0);
return;
}
uint8_t cc = 0;
uint16_t reasonCode = 0;
int32_t threshold = 0;
auto rc = gpu::decodeReadThermalParametersResponse(
*new (respMsg.data()) ocp::accelerator_management::Message,
respMsg.size(), cc, reasonCode, threshold);
if (rc != ocp::accelerator_management::CompletionCode::SUCCESS ||
cc != static_cast<uint8_t>(
ocp::accelerator_management::CompletionCode::SUCCESS))
{
lg2::error(
"decodeReadThermalParametersResponse() failed, rc={RC} cc={CC} reasonCode={RESC}",
"RC", static_cast<int>(rc), "CC", cc, "RESC", reasonCode);
callback(-4, 0);
return;
}
callback(0, threshold);
});
}
void readThermalParameterCallback(
uint8_t eid, const std::shared_ptr<std::vector<uint8_t>>& ids,
mctp::MctpRequester& mctpRequester,
const std::function<void(uint8_t, std::vector<int32_t>)>& callback,
size_t index, const std::shared_ptr<std::vector<int32_t>>& thresholds,
uint8_t rc, int32_t threshold)
{
if (rc != 0)
{
callback(rc, *thresholds);
return;
}
thresholds->push_back(threshold);
++index;
if (index == ids->size())
{
callback(rc, *thresholds);
}
else
{
readThermalParameter(eid, (*ids)[index], mctpRequester,
std::bind_front(readThermalParameterCallback, eid,
ids, std::ref(mctpRequester),
callback, index, thresholds));
}
}
void readThermalParametersBatched(
uint8_t eid, const std::shared_ptr<std::vector<uint8_t>>& ids,
mctp::MctpRequester& mctpRequester,
const std::function<void(uint8_t, std::vector<int32_t>)>& callback)
{
auto thresholds = std::make_shared<std::vector<int32_t>>();
size_t index = 0;
readThermalParameter(
eid, (*ids)[index], mctpRequester,
std::bind_front(readThermalParameterCallback, eid, ids,
std::ref(mctpRequester), callback, index, thresholds));
}