summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dcmihandler.cpp65
-rw-r--r--dcmihandler.hpp33
2 files changed, 98 insertions, 0 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp
index 2e0204d..11a3730 100644
--- a/dcmihandler.cpp
+++ b/dcmihandler.cpp
@@ -74,6 +74,27 @@ bool getPcapEnabled(sdbusplus::bus::bus& bus)
return pcapEnabled.get<bool>();
}
+void setPcap(sdbusplus::bus::bus& bus, const uint32_t powerCap)
+{
+ auto service = ipmi::getService(bus, PCAP_INTERFACE, PCAP_PATH);
+
+ auto method = bus.new_method_call(service.c_str(),
+ PCAP_PATH,
+ "org.freedesktop.DBus.Properties",
+ "Set");
+
+ method.append(PCAP_INTERFACE, POWER_CAP_PROP);
+ method.append(sdbusplus::message::variant<uint32_t>(powerCap));
+
+ auto reply = bus.call(method);
+
+ if (reply.is_method_error())
+ {
+ log<level::ERR>("Error in setPcap property");
+ elog<InternalFailure>();
+ }
+}
+
void readAssetTagObjectTree(dcmi::assettag::ObjectTree& objectTree)
{
static constexpr auto mapperBusName = "xyz.openbmc_project.ObjectMapper";
@@ -228,6 +249,45 @@ ipmi_ret_t getPowerLimit(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
}
}
+ipmi_ret_t setPowerLimit(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
+ ipmi_request_t request, ipmi_response_t response,
+ ipmi_data_len_t data_len, ipmi_context_t context)
+{
+ auto requestData = reinterpret_cast<const dcmi::SetPowerLimitRequest*>
+ (request);
+ std::vector<uint8_t> outPayload(sizeof(dcmi::SetPowerLimitResponse));
+ auto responseData = reinterpret_cast<dcmi::SetPowerLimitResponse*>
+ (outPayload.data());
+
+ if (requestData->groupID != dcmi::groupExtId)
+ {
+ *data_len = 0;
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ sdbusplus::bus::bus sdbus {ipmid_get_sd_bus_connection()};
+
+ // Only process the power limit requested in watts.
+ try
+ {
+ dcmi::setPcap(sdbus, requestData->powerLimit);
+ }
+ catch (InternalFailure& e)
+ {
+ *data_len = 0;
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ log<level::INFO>("Set Power Cap",
+ entry("POWERCAP=%u", requestData->powerLimit));
+
+ responseData->groupID = dcmi::groupExtId;
+ memcpy(response, outPayload.data(), outPayload.size());
+ *data_len = outPayload.size();
+
+ return IPMI_CC_OK;
+}
+
ipmi_ret_t getAssetTag(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request, ipmi_response_t response,
ipmi_data_len_t data_len, ipmi_context_t context)
@@ -370,6 +430,11 @@ void register_netfn_dcmi_functions()
ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_POWER_LIMIT, NULL, getPowerLimit,
PRIVILEGE_USER);
+ // <Set Power Limit>
+ printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_SET_POWER_LIMIT);
+ ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_SET_POWER_LIMIT, NULL, setPowerLimit,
+ PRIVILEGE_OPERATOR);
+
// <Get Asset Tag>
printf("Registering NetFn:[0x%X], Cmd:[0x%X]\n",NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_ASSET_TAG);
ipmi_register_callback(NETFUN_GRPEXT, IPMI_CMD_DCMI_GET_ASSET_TAG, NULL, getAssetTag,
diff --git a/dcmihandler.hpp b/dcmihandler.hpp
index 8ebc660..e318294 100644
--- a/dcmihandler.hpp
+++ b/dcmihandler.hpp
@@ -11,6 +11,7 @@ enum ipmi_netfn_sen_cmds
{
// Get capability bits
IPMI_CMD_DCMI_GET_POWER_LIMIT = 0x03,
+ IPMI_CMD_DCMI_SET_POWER_LIMIT = 0x04,
IPMI_CMD_DCMI_GET_ASSET_TAG = 0x06,
IPMI_CMD_DCMI_SET_ASSET_TAG = 0x08,
};
@@ -145,6 +146,38 @@ struct GetPowerLimitResponse
uint16_t samplingPeriod; //!< Statistics sampling period in seconds.
} __attribute__((packed));
+/** @brief Set the power cap value
+ *
+ * @param[in] bus - dbus connection
+ * @param[in] powerCap - power cap value
+ */
+void setPcap(sdbusplus::bus::bus& bus, const uint32_t powerCap);
+
+/** @struct SetPowerLimitRequest
+ *
+ * DCMI payload for Set Power Limit command request.
+ */
+struct SetPowerLimitRequest
+{
+ uint8_t groupID; //!< Group extension identification.
+ uint16_t reserved; //!< Reserved
+ uint8_t reserved1; //!< Reserved
+ uint8_t exceptionAction; //!< Exception action.
+ uint16_t powerLimit; //!< Power limit requested in watts.
+ uint32_t correctionTime; //!< Correction time limit in milliseconds.
+ uint16_t reserved2; //!< Reserved.
+ uint16_t samplingPeriod; //!< Statistics sampling period in seconds.
+} __attribute__((packed));
+
+/** @struct SetPowerLimitResponse
+ *
+ * DCMI payload for Set Power Limit command response.
+ */
+struct SetPowerLimitResponse
+{
+ uint8_t groupID; //!< Group extension identification.
+} __attribute__((packed));
+
} // namespace dcmi
#endif
OpenPOWER on IntegriCloud