Add slot ipmb command
Added slot ipmb command which is used to send commands to add-in cards.
BMC will act as a bridge and forwards the data to the add-in card and
returns the response from the add-in card.
Tested:
ipmitool raw 0x3e 0x51 <address_type> <slot_num> <slave_addr> <net_fun>
<cmd>
00 //success
ipmitool raw 0x3e 0x51 <address_type> <invalid_slot_num> <slave_addr>
<net_fun> <cmd>
0xce //Command response could not be provided
ipmitool raw 0x3e 0x51 <address_type> <slot_num> <invalid_slave_addr>
<net_fun> <cmd>
0xce //Command response could not be provided
Tested the command from the shell using cmdtool via KCS interface and it
works fine.
Signed-off-by: Rajashekar Gade Reddy <raja.sekhar.reddy.gade@linux.intel.com>
Change-Id: Ic772e169569ee91328315a02633089d3894e1b0f
diff --git a/include/oemcommands.hpp b/include/oemcommands.hpp
index 7a8e445..13586c5 100644
--- a/include/oemcommands.hpp
+++ b/include/oemcommands.hpp
@@ -106,6 +106,7 @@
static constexpr Cmd cmdMdrIIDataStart = 0x3b;
static constexpr Cmd cmdMdrIIDataDone = 0x3c;
static constexpr Cmd cmdMdrIISendDataBlock = 0x3d;
+static constexpr Cmd cmdSlotIpmb = 0x51;
} // namespace app
} // namespace intel
diff --git a/src/oemcommands.cpp b/src/oemcommands.cpp
index 7adb36a..2d639fb 100644
--- a/src/oemcommands.cpp
+++ b/src/oemcommands.cpp
@@ -606,6 +606,49 @@
return ipmi::responseSuccess();
}
+ipmi::RspType<uint8_t, std::vector<uint8_t>>
+ ipmiOEMSlotIpmb(ipmi::Context::ptr ctx, uint6_t reserved1,
+ uint2_t slotNumber, uint3_t baseBoardSlotNum,
+ uint3_t riserSlotNum, uint2_t reserved2, uint8_t slaveAddr,
+ uint8_t netFn, uint8_t cmd,
+ std::optional<std::vector<uint8_t>> writeData)
+{
+ if (reserved1 || reserved2)
+ {
+ return ipmi::responseInvalidFieldRequest();
+ }
+
+ boost::system::error_code ec;
+ using ipmbResponse = std::tuple<int, uint8_t, uint8_t, uint8_t, uint8_t,
+ std::vector<uint8_t>>;
+ ipmbResponse res = ctx->bus->yield_method_call<ipmbResponse>(
+ ctx->yield, ec, "xyz.openbmc_project.Ipmi.Channel.Ipmb",
+ "/xyz/openbmc_project/Ipmi/Channel/Ipmb", "org.openbmc.Ipmb",
+ "SlotIpmbRequest", static_cast<uint8_t>(slotNumber),
+ static_cast<uint8_t>(baseBoardSlotNum), slaveAddr, netFn, cmd,
+ *writeData);
+ if (ec)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Failed to call dbus method SlotIpmbRequest");
+ return ipmi::responseUnspecifiedError();
+ }
+
+ std::vector<uint8_t> dataReceived(0);
+ int status = -1;
+ uint8_t resNetFn = 0, resLun = 0, resCmd = 0, cc = 0;
+
+ std::tie(status, resNetFn, resLun, resCmd, cc, dataReceived) = res;
+
+ if (status)
+ {
+ phosphor::logging::log<phosphor::logging::level::ERR>(
+ "Failed to get response from SlotIpmbRequest");
+ return ipmi::responseResponseError();
+ }
+ return ipmi::responseSuccess(cc, dataReceived);
+}
+
ipmi_ret_t ipmiOEMSetPowerRestoreDelay(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request,
ipmi_response_t response,
@@ -3545,6 +3588,9 @@
intel::general::cmdSendEmbeddedFWUpdStatus,
Privilege::Operator, ipmiOEMSendEmbeddedFwUpdStatus);
+ registerHandler(prioOpenBmcBase, intel::netFnApp, intel::app::cmdSlotIpmb,
+ Privilege::Admin, ipmiOEMSlotIpmb);
+
ipmiPrintAndRegister(intel::netFnGeneral,
intel::general::cmdSetPowerRestoreDelay, NULL,
ipmiOEMSetPowerRestoreDelay, PRIVILEGE_OPERATOR);