summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNagaraju Goruganti <ngorugan@in.ibm.com>2018-02-07 01:19:59 -0600
committerTom Joseph <tomjoseph@in.ibm.com>2018-02-22 06:45:26 +0000
commit22be97b3f5331106b3dab8101a0df8392abf3ea2 (patch)
treeb6842f12bdd752ae9a5f101806986ebe64492530
parent73f44518bdafd438f800d31d47ee9176d42cc83f (diff)
downloadphosphor-host-ipmid-22be97b3f5331106b3dab8101a0df8392abf3ea2.tar.gz
phosphor-host-ipmid-22be97b3f5331106b3dab8101a0df8392abf3ea2.zip
DCMI: Add get/set Configuration Parameters command
1.Systemd-networkd doesn't allow to configure DHCP timings, so set is not implemented. 2.Get command to DHCP timings will return hardcoded values from systemd-networkd source code. 3.Systemd-networkd doesn't support Random Back off, so not implemented. 4.As the info about VendorClassIdentifier is not clear in the spec, Right now we are not supporting DHCP Option 60 and Option 43. We will open new issue for it. Resolves openbmc/openbmc#2752 Change-Id: I2682e5e43ceb19647e5240b095f601777213530b Signed-off-by: Nagaraju Goruganti <ngorugan@in.ibm.com>
-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