summaryrefslogtreecommitdiff
path: root/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch')
-rw-r--r--meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch356
1 files changed, 356 insertions, 0 deletions
diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch
new file mode 100644
index 000000000..ba8896195
--- /dev/null
+++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0059-Move-Set-SOL-config-parameter-to-host-ipmid.patch
@@ -0,0 +1,356 @@
+From 9f4fb8a6aa076261b19c187aeef840d818158ec7 Mon Sep 17 00:00:00 2001
+From: Cheng C Yang <cheng.c.yang@intel.com>
+Date: Wed, 16 Oct 2019 14:24:20 +0800
+Subject: [PATCH] Move Set SOL config parameter to host-ipmid
+
+Move Set SOL config parameter command from net-ipmid to host-ipmid,
+so that BIOS in Intel platform can enable or disable SOL through KCS.
+Get SOL config parameter command will be moved later.
+
+Tested by:
+With the related change in phospher-ipmi-net and phospher-dbus-interface,
+Run commands:
+ipmitool raw 0x0c 0x21 0x0e 0x00 0x01
+ipmitool raw 0x0c 0x21 0x0e 0x01 0x00
+ipmitool raw 0x0c 0x21 0x0e 0x02 0x03
+ipmitool raw 0x0c 0x21 0x0e 0x03 0x5 0x03
+ipmitool raw 0x0c 0x21 0x0e 0x04 0x5 0x03
+All these commands have correct response and all dbus interface for
+sol command change to same value in above commands.
+After reboot BMC, "Progress" property in dbus interface change back
+to 0 and other properties will not reset to default value.
+
+Signed-off-by: Cheng C Yang <cheng.c.yang@intel.com>
+Signed-off-by: James Feist <james.feist@linux.intel.com>
+---
+ host-ipmid-whitelist.conf | 1 +
+ transporthandler.cpp | 294 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 295 insertions(+)
+
+diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
+index 5397115..c93f3b1 100644
+--- a/host-ipmid-whitelist.conf
++++ b/host-ipmid-whitelist.conf
+@@ -41,6 +41,7 @@
+ 0x0A:0x48 //<Storage>:<Get SEL Time>
+ 0x0A:0x49 //<Storage>:<Set SEL Time>
+ 0x0C:0x02 //<Transport>:<Get LAN Configuration Parameters>
++0x0C:0x21 //<Transport>:<Set SOL Configuration Parameters>
+ 0x2C:0x00 //<Group Extension>:<Group Extension Command>
+ 0x2C:0x01 //<Group Extension>:<Get DCMI Capabilities>
+ 0x2C:0x02 //<Group Extension>:<Get Power Reading>
+diff --git a/transporthandler.cpp b/transporthandler.cpp
+index 0012746..0de76c4 100644
+--- a/transporthandler.cpp
++++ b/transporthandler.cpp
+@@ -2030,8 +2030,298 @@ RspType<message::Payload> getLan(Context::ptr ctx, uint4_t channelBits,
+ } // namespace transport
+ } // namespace ipmi
+
++constexpr const char* solInterface = "xyz.openbmc_project.Ipmi.SOL";
++constexpr const char* solPath = "/xyz/openbmc_project/ipmi/sol/";
++
+ void register_netfn_transport_functions() __attribute__((constructor));
+
++static std::string
++ getSOLService(std::shared_ptr<sdbusplus::asio::connection> dbus,
++ const std::string& solPathWitheEthName)
++{
++ static std::string solService{};
++ if (solService.empty())
++ {
++ try
++ {
++ solService =
++ ipmi::getService(*dbus, solInterface, solPathWitheEthName);
++ }
++ catch (const sdbusplus::exception::SdBusError& e)
++ {
++ solService.clear();
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error: get SOL service failed");
++ return solService;
++ }
++ }
++ return solService;
++}
++
++static int setSOLParameter(const std::string& property,
++ const ipmi::Value& value, const uint8_t& channelNum)
++{
++ auto dbus = getSdBus();
++
++ std::string ethdevice = ipmi::getChannelName(channelNum);
++
++ std::string solPathWitheEthName = std::string(solPath) + ethdevice;
++
++ std::string service = getSOLService(dbus, solPathWitheEthName);
++ if (service.empty())
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to get SOL service failed");
++ return -1;
++ }
++ try
++ {
++ ipmi::setDbusProperty(*dbus, service, solPathWitheEthName, solInterface,
++ property, value);
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error setting sol parameter");
++ return -1;
++ }
++
++ return 0;
++}
++
++static int getSOLParameter(const std::string& property, ipmi::Value& value,
++ const uint8_t& channelNum)
++{
++ auto dbus = getSdBus();
++
++ std::string ethdevice = ipmi::getChannelName(channelNum);
++
++ std::string solPathWitheEthName = std::string(solPath) + ethdevice;
++
++ std::string service = getSOLService(dbus, solPathWitheEthName);
++ if (service.empty())
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Unable to get SOL service failed");
++ return -1;
++ }
++ try
++ {
++ value = ipmi::getDbusProperty(*dbus, service, solPathWitheEthName,
++ solInterface, property);
++ }
++ catch (sdbusplus::exception_t&)
++ {
++ phosphor::logging::log<phosphor::logging::level::ERR>(
++ "Error getting sol parameter");
++ return -1;
++ }
++
++ return 0;
++}
++
++static const constexpr uint8_t encryptMask = 0x80;
++static const constexpr uint8_t encryptShift = 7;
++static const constexpr uint8_t authMask = 0x40;
++static const constexpr uint8_t authShift = 6;
++static const constexpr uint8_t privilegeMask = 0xf;
++
++namespace ipmi
++{
++constexpr Cc ccParmNotSupported = 0x80;
++constexpr Cc ccSetInProgressActive = 0x81;
++constexpr Cc ccSystemInfoParameterSetReadOnly = 0x82;
++
++static inline auto responseParmNotSupported()
++{
++ return response(ccParmNotSupported);
++}
++static inline auto responseSetInProgressActive()
++{
++ return response(ccSetInProgressActive);
++}
++static inline auto responseSystemInfoParameterSetReadOnly()
++{
++ return response(ccSystemInfoParameterSetReadOnly);
++}
++
++} // namespace ipmi
++
++namespace sol
++{
++enum class Parameter
++{
++ progress, //!< Set In Progress.
++ enable, //!< SOL Enable.
++ authentication, //!< SOL Authentication.
++ accumulate, //!< Character Accumulate Interval & Send Threshold.
++ retry, //!< SOL Retry.
++ nvbitrate, //!< SOL non-volatile bit rate.
++ vbitrate, //!< SOL volatile bit rate.
++ channel, //!< SOL payload channel.
++ port, //!< SOL payload port.
++};
++
++enum class Privilege : uint8_t
++{
++ highestPriv,
++ callbackPriv,
++ userPriv,
++ operatorPriv,
++ adminPriv,
++ oemPriv,
++};
++
++} // namespace sol
++
++constexpr uint8_t progressMask = 0x03;
++constexpr uint8_t enableMask = 0x01;
++constexpr uint8_t retryMask = 0x07;
++
++ipmi::RspType<> setSOLConfParams(ipmi::Context::ptr ctx, uint4_t chNum,
++ uint4_t reserved, uint8_t paramSelector,
++ uint8_t configParamData1,
++ std::optional<uint8_t> configParamData2)
++{
++ ipmi::ChannelInfo chInfo;
++ uint8_t channelNum = ipmi::convertCurrentChannelNum(
++ static_cast<uint8_t>(chNum), ctx->channel);
++ if (reserved != 0 ||
++ (!ipmi::isValidChannel(static_cast<uint8_t>(channelNum))))
++ {
++ return ipmi::responseInvalidFieldRequest();
++ }
++
++ ipmi_ret_t compCode =
++ ipmi::getChannelInfo(static_cast<uint8_t>(channelNum), chInfo);
++ if (compCode != IPMI_CC_OK ||
++ chInfo.mediumType !=
++ static_cast<uint8_t>(ipmi::EChannelMediumType::lan8032))
++ {
++ return ipmi::responseInvalidFieldRequest();
++ }
++
++ switch (static_cast<sol::Parameter>(paramSelector))
++ {
++ case sol::Parameter::progress:
++ {
++ if (configParamData2)
++ {
++ return ipmi::responseReqDataLenInvalid();
++ }
++ uint8_t progress = configParamData1 & progressMask;
++ ipmi::Value currentProgress = 0;
++ if (getSOLParameter("Progress", currentProgress, channelNum) < 0)
++ {
++ return ipmi::responseUnspecifiedError();
++ }
++
++ if ((std::get<uint8_t>(currentProgress) == 1) && (progress == 1))
++ {
++ return ipmi::responseSetInProgressActive();
++ }
++
++ if (setSOLParameter("Progress", progress, channelNum) < 0)
++ {
++ return ipmi::responseUnspecifiedError();
++ }
++ break;
++ }
++ case sol::Parameter::enable:
++ {
++ if (configParamData2)
++ {
++ return ipmi::responseReqDataLenInvalid();
++ }
++ bool enable = configParamData1 & enableMask;
++ if (setSOLParameter("Enable", enable, channelNum) < 0)
++ {
++ return ipmi::responseUnspecifiedError();
++ }
++ break;
++ }
++ case sol::Parameter::authentication:
++ {
++ if (configParamData2)
++ {
++ return ipmi::responseReqDataLenInvalid();
++ }
++ uint8_t encrypt = (configParamData1 & encryptMask) >> encryptShift;
++ uint8_t auth = (configParamData1 & authMask) >> authShift;
++ uint8_t privilege = configParamData1 & privilegeMask;
++ // For security considering encryption and authentication must be
++ // true.
++ if (!encrypt || !auth)
++ {
++ return ipmi::responseSystemInfoParameterSetReadOnly();
++ }
++ else if (privilege <
++ static_cast<uint8_t>(sol::Privilege::userPriv) ||
++ privilege > static_cast<uint8_t>(sol::Privilege::oemPriv))
++ {
++ return ipmi::responseInvalidFieldRequest();
++ }
++
++ if (setSOLParameter("Privilege", privilege, channelNum) < 0)
++ {
++ return ipmi::responseUnspecifiedError();
++ }
++
++ break;
++ }
++ case sol::Parameter::accumulate:
++ {
++ if (!configParamData2)
++ {
++ return ipmi::responseReqDataLenInvalid();
++ }
++ if (*configParamData2 == 0)
++ {
++ return ipmi::responseInvalidFieldRequest();
++ }
++ if (setSOLParameter("AccumulateIntervalMS", configParamData1,
++ channelNum) < 0)
++ {
++ return ipmi::responseUnspecifiedError();
++ }
++ if (setSOLParameter("Threshold", *configParamData2, channelNum) < 0)
++ {
++ return ipmi::responseUnspecifiedError();
++ }
++ break;
++ }
++ case sol::Parameter::retry:
++ {
++ if (!configParamData2)
++ {
++ return ipmi::responseReqDataLenInvalid();
++ }
++ if ((setSOLParameter(
++ "RetryCount",
++ static_cast<uint8_t>(configParamData1 & retryMask),
++ channelNum) < 0) ||
++ (setSOLParameter("RetryIntervalMS", *configParamData2,
++ channelNum) < 0))
++ {
++ return ipmi::responseUnspecifiedError();
++ }
++
++ break;
++ }
++ case sol::Parameter::port:
++ {
++ return ipmi::responseSystemInfoParameterSetReadOnly();
++ }
++ case sol::Parameter::nvbitrate:
++ case sol::Parameter::vbitrate:
++ case sol::Parameter::channel:
++ default:
++ return ipmi::responseParmNotSupported();
++ }
++
++ return ipmi::responseSuccess();
++}
++
+ void register_netfn_transport_functions()
+ {
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
+@@ -2040,4 +2330,8 @@ void register_netfn_transport_functions()
+ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
+ ipmi::transport::cmdGetLanConfigParameters,
+ ipmi::Privilege::Operator, ipmi::transport::getLan);
++
++ ipmi::registerHandler(ipmi::prioOpenBmcBase, ipmi::netFnTransport,
++ ipmi::transport::cmdSetSolConfigParameters,
++ ipmi::Privilege::Admin, setSOLConfParams);
+ }
+--
+2.17.1
+