summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dcmihandler.cpp213
-rw-r--r--dcmihandler.hpp76
2 files changed, 289 insertions, 0 deletions
diff --git a/dcmihandler.cpp b/dcmihandler.cpp
index fa3b55b..c077aa5 100644
--- a/dcmihandler.cpp
+++ b/dcmihandler.cpp
@@ -13,6 +13,7 @@
#include <cmath>
#include "xyz/openbmc_project/Common/error.hpp"
#include "config.h"
+#include "net.hpp"
using namespace phosphor::logging;
using InternalFailure =
@@ -29,6 +30,24 @@ constexpr auto POWER_CAP_ENABLE_PROP = "PowerCapEnable";
constexpr auto DCMI_PARAMETER_REVISION = 2;
constexpr auto DCMI_SPEC_MAJOR_VERSION = 1;
constexpr auto DCMI_SPEC_MINOR_VERSION = 5;
+constexpr auto DCMI_CONFIG_PARAMETER_REVISION = 1;
+constexpr auto DCMI_RAND_BACK_OFF_MASK = 0x80;
+constexpr auto DCMI_OPTION_60_43_MASK = 0x02;
+constexpr auto DCMI_OPTION_12_MASK = 0x01;
+constexpr auto DCMI_ACTIVATE_DHCP_MASK = 0x01;
+constexpr auto DCMI_ACTIVATE_DHCP_REPLY = 0x00;
+constexpr auto DCMI_SET_CONF_PARAM_REQ_PACKET_MAX_SIZE = 0x05;
+constexpr auto DCMI_SET_CONF_PARAM_REQ_PACKET_MIN_SIZE = 0x04;
+constexpr auto DHCP_TIMING1 = 0x04; // 4 sec
+constexpr auto DHCP_TIMING2_UPPER = 0x00; //2 min
+constexpr auto DHCP_TIMING2_LOWER = 0x78;
+constexpr auto DHCP_TIMING3_UPPER = 0x00; //64 sec
+constexpr auto DHCP_TIMING3_LOWER = 0x40;
+// When DHCP Option 12 is enabled the string "SendHostName=true" will be
+// added into n/w configuration file and the parameter
+// SendHostNameEnabled will set to true.
+constexpr auto DHCP_OPT12_ENABLED = "SendHostNameEnabled";
+
constexpr auto DCMI_CAP_JSON_FILE = "/usr/share/ipmi-providers/dcmi_cap.json";
constexpr auto SENSOR_VALUE_INTF = "xyz.openbmc_project.Sensor.Value";
@@ -244,6 +263,40 @@ std::string getHostName(void)
return value.get<std::string>();
}
+bool getDHCPEnabled()
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+
+ auto ethdevice = ipmi::network::ChanneltoEthernet(
+ ethernetDefaultChannelNum);
+ auto ethernetObj = ipmi::getDbusObject(bus, ethernetIntf, networkRoot,
+ ethdevice);
+ auto service = ipmi::getService(bus, ethernetIntf, ethernetObj.first);
+ auto value = ipmi::getDbusProperty(bus, service,
+ ethernetObj.first, ethernetIntf, "DHCPEnabled");
+
+ return value.get<bool>();
+}
+
+bool getDHCPOption(std::string prop)
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+
+ auto service = ipmi::getService(bus, dhcpIntf, dhcpObj);
+ auto value = ipmi::getDbusProperty(bus, service, dhcpObj, dhcpIntf, prop);
+
+ return value.get<bool>();
+}
+
+
+void setDHCPOption(std::string prop, bool value)
+{
+ sdbusplus::bus::bus bus{ipmid_get_sd_bus_connection()};
+
+ auto service = ipmi::getService(bus, dhcpIntf, dhcpObj);
+ ipmi::setDbusProperty(bus, service, dhcpObj, dhcpIntf, prop, value);
+}
+
Json parseSensorConfig()
{
std::ifstream jsonFile(configFile);
@@ -1063,6 +1116,158 @@ int64_t getPowerReading(sdbusplus::bus::bus& bus)
return power;
}
+ipmi_ret_t setDCMIConfParams(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::SetConfParamsRequest*>
+ (request);
+ auto responseData = reinterpret_cast<dcmi::SetConfParamsResponse*>
+ (response);
+
+
+ if (requestData->groupID != dcmi::groupExtId || *data_len <
+ DCMI_SET_CONF_PARAM_REQ_PACKET_MIN_SIZE || *data_len >
+ DCMI_SET_CONF_PARAM_REQ_PACKET_MAX_SIZE)
+ {
+ log<level::ERR>("Invalid Group ID or Invaild Requested Packet size",
+ entry("GROUP_ID=%d", requestData->groupID),
+ entry("PACKET SIZE=%d", *data_len));
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ *data_len = 0;
+
+ try
+ {
+ // Take action based on the Parameter Selector
+ switch (static_cast<dcmi::DCMIConfigParameters>(
+ requestData->paramSelect))
+ {
+ case dcmi::DCMIConfigParameters::ActivateDHCP:
+
+ if ((requestData->data[0] & DCMI_ACTIVATE_DHCP_MASK) &&
+ dcmi::getDHCPEnabled())
+ {
+ // When these conditions are met we have to trigger DHCP
+ // protocol restart using the latest parameter settings, but
+ // as per n/w manager design, each time when we update n/w
+ // parameters, n/w service is restarted. So we no need to take
+ // any action in this case.
+ }
+ break;
+
+ case dcmi::DCMIConfigParameters::DiscoveryConfig:
+
+ if (requestData->data[0] & DCMI_OPTION_12_MASK)
+ {
+ dcmi::setDHCPOption(DHCP_OPT12_ENABLED, true);
+ }
+ else
+ {
+ dcmi::setDHCPOption(DHCP_OPT12_ENABLED, false);
+ }
+
+ // Systemd-networkd doesn't support Random Back off
+ if (requestData->data[0] & DCMI_RAND_BACK_OFF_MASK)
+ {
+ return IPMI_CC_INVALID;
+ }
+ break;
+ // Systemd-networkd doesn't allow to configure DHCP timigs
+ case dcmi::DCMIConfigParameters::DHCPTiming1:
+ case dcmi::DCMIConfigParameters::DHCPTiming2:
+ case dcmi::DCMIConfigParameters::DHCPTiming3:
+ default:
+ return IPMI_CC_INVALID;
+ }
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+ responseData->groupID = dcmi::groupExtId;
+ *data_len = sizeof(dcmi::SetConfParamsResponse);
+
+ return IPMI_CC_OK;
+}
+
+ipmi_ret_t getDCMIConfParams(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::GetConfParamsRequest*>
+ (request);
+ auto responseData = reinterpret_cast<dcmi::GetConfParamsResponse*>
+ (response);
+
+ responseData->data[0] = 0x00;
+
+ if (requestData->groupID != dcmi::groupExtId || *data_len != sizeof(
+ dcmi::GetConfParamsRequest))
+ {
+ log<level::ERR>("Invalid Group ID or Invaild Requested Packet size",
+ entry("GROUP_ID=%d", requestData->groupID),
+ entry("PACKET SIZE=%d", *data_len));
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ *data_len = 0;
+
+ try
+ {
+ // Take action based on the Parameter Selector
+ switch (static_cast<dcmi::DCMIConfigParameters>(
+ requestData->paramSelect))
+ {
+ case dcmi::DCMIConfigParameters::ActivateDHCP:
+ responseData->data[0] = DCMI_ACTIVATE_DHCP_REPLY;
+ *data_len = sizeof(dcmi::GetConfParamsResponse) + 1;
+ break;
+ case dcmi::DCMIConfigParameters::DiscoveryConfig:
+ if (dcmi::getDHCPOption(DHCP_OPT12_ENABLED))
+ {
+ responseData->data[0] |= DCMI_OPTION_12_MASK;
+ }
+ *data_len = sizeof(dcmi::GetConfParamsResponse) + 1;
+ break;
+ // Get below values from Systemd-networkd source code
+ case dcmi::DCMIConfigParameters::DHCPTiming1:
+ responseData->data[0] = DHCP_TIMING1;
+ *data_len = sizeof(dcmi::GetConfParamsResponse) + 1;
+ break;
+ case dcmi::DCMIConfigParameters::DHCPTiming2:
+ responseData->data[0] = DHCP_TIMING2_LOWER;
+ responseData->data[1] = DHCP_TIMING2_UPPER;
+ *data_len = sizeof(dcmi::GetConfParamsResponse) + 2;
+ break;
+ case dcmi::DCMIConfigParameters::DHCPTiming3:
+ responseData->data[0] = DHCP_TIMING3_LOWER;
+ responseData->data[1] = DHCP_TIMING3_UPPER;
+ *data_len = sizeof(dcmi::GetConfParamsResponse) + 2;
+ break;
+ default:
+ *data_len = 0;
+ return IPMI_CC_INVALID;
+ }
+ }
+ catch (std::exception& e)
+ {
+ log<level::ERR>(e.what());
+ return IPMI_CC_UNSPECIFIED_ERROR;
+ }
+
+ responseData->groupID = dcmi::groupExtId;
+ responseData->major = DCMI_SPEC_MAJOR_VERSION;
+ responseData->minor = DCMI_SPEC_MINOR_VERSION;
+ responseData->paramRevision = DCMI_CONFIG_PARAMETER_REVISION;
+
+ return IPMI_CC_OK;
+}
+
+
ipmi_ret_t getPowerReading(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)
@@ -1364,6 +1569,14 @@ void register_netfn_dcmi_functions()
ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_SENSOR_INFO,
NULL, getSensorInfo, PRIVILEGE_USER);
+ // <Get DCMI Configuration Parameters>
+ ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::GET_CONF_PARAMS,
+ NULL, getDCMIConfParams, PRIVILEGE_USER);
+
+ // <Set DCMI Configuration Parameters>
+ ipmi_register_callback(NETFUN_GRPEXT, dcmi::Commands::SET_CONF_PARAMS,
+ NULL, setDCMIConfParams, PRIVILEGE_ADMIN);
+
return;
}
// 956379
diff --git a/dcmihandler.hpp b/dcmihandler.hpp
index e2a4c10..5388344 100644
--- a/dcmihandler.hpp
+++ b/dcmihandler.hpp
@@ -27,6 +27,8 @@ enum Commands
GET_MGMNT_CTRL_ID_STR = 0x09,
SET_MGMNT_CTRL_ID_STR = 0x0A,
GET_TEMP_READINGS = 0x10,
+ SET_CONF_PARAMS = 0x12,
+ GET_CONF_PARAMS = 0x13,
};
static constexpr auto propIntf = "org.freedesktop.DBus.Properties";
@@ -43,6 +45,16 @@ static constexpr auto temperatureSensorType = 0x01;
static constexpr auto maxInstances = 255;
static constexpr auto configFile =
"/usr/share/ipmi-providers/dcmi_sensors.json";
+static constexpr auto ethernetIntf =
+ "xyz.openbmc_project.Network.EthernetInterface";
+static constexpr auto ethernetDefaultChannelNum = 0x1;
+static constexpr auto networkRoot = "/xyz/openbmc_project/network";
+static constexpr auto dhcpObj = "/xyz/openbmc_project/network/config/dhcp";
+static constexpr auto dhcpIntf =
+ "xyz.openbmc_project.Network.DHCPConfiguration";
+static constexpr auto systemBusName = "org.freedesktop.systemd1";
+static constexpr auto systemPath = "/org/freedesktop/systemd1";
+static constexpr auto systemIntf = "org.freedesktop.systemd1.Manager";
namespace assettag
{
@@ -552,6 +564,70 @@ struct GetSensorInfoResponseHdr
uint8_t numInstances; //!< No. of instances for requested id
uint8_t numRecords; //!< No. of record ids in the response
} __attribute__((packed));
+/**
+ * @brief Parameters for DCMI Configuration Parameters
+ */
+enum class DCMIConfigParameters: uint8_t
+{
+ ActivateDHCP = 1,
+ DiscoveryConfig,
+ DHCPTiming1,
+ DHCPTiming2,
+ DHCPTiming3,
+};
+
+/** @struct SetConfParamsRequest
+ *
+ * DCMI Set DCMI Configuration Parameters Command.
+ * Refer DCMI specification Version 1.1 Section 6.1.2
+ */
+struct SetConfParamsRequest
+{
+ uint8_t groupID; //!< Group extension identification.
+ uint8_t paramSelect; //!< Parameter selector.
+ uint8_t setSelect; //!< Set Selector (use 00h for parameters that only
+ //!< have one set).
+ uint8_t data[]; //!< Configuration parameter data.
+} __attribute__((packed));
+
+/** @struct SetConfParamsResponse
+ *
+ * DCMI Set DCMI Configuration Parameters Command response.
+ * Refer DCMI specification Version 1.1 Section 6.1.2
+ */
+struct SetConfParamsResponse
+{
+ uint8_t groupID; //!< Group extension identification.
+} __attribute__((packed));
+
+/** @struct GetConfParamsRequest
+ *
+ * DCMI Get DCMI Configuration Parameters Command.
+ * Refer DCMI specification Version 1.1 Section 6.1.3
+ */
+struct GetConfParamsRequest
+{
+ uint8_t groupID; //!< Group extension identification.
+ uint8_t paramSelect; //!< Parameter selector.
+ uint8_t setSelect; //!< Set Selector. Selects a given set of parameters
+ //!< under a given Parameter selector value. 00h if
+ //!< parameter doesn't use a Set Selector.
+} __attribute__((packed));
+
+/** @struct GetConfParamsResponse
+ *
+ * DCMI Get DCMI Configuration Parameters Command response.
+ * Refer DCMI specification Version 1.1 Section 6.1.3
+ */
+struct GetConfParamsResponse
+{
+ uint8_t groupID; //!< Group extension identification.
+ uint8_t major; //!< DCMI Spec Conformance - major ver = 01h.
+ uint8_t minor; //!< DCMI Spec Conformance - minor ver = 05h.
+ uint8_t paramRevision; //!< Parameter Revision = 01h.
+ uint8_t data[]; //!< Parameter data.
+
+} __attribute__((packed));
} // namespace dcmi
OpenPOWER on IntegriCloud