summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/usr/ipmi/ipmi_reasoncodes.H4
-rw-r--r--src/include/usr/ipmi/ipmiif.H8
-rw-r--r--src/usr/ipmiext/ipmidcmi.C131
3 files changed, 139 insertions, 4 deletions
diff --git a/src/include/usr/ipmi/ipmi_reasoncodes.H b/src/include/usr/ipmi/ipmi_reasoncodes.H
index 65d8e64d3..6bb7e4b4b 100644
--- a/src/include/usr/ipmi/ipmi_reasoncodes.H
+++ b/src/include/usr/ipmi/ipmi_reasoncodes.H
@@ -5,9 +5,10 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2014,2017 */
+/* Contributors Listed Below - COPYRIGHT 2014,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
+/* [+] Maxim Polyakov */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -64,6 +65,7 @@ namespace IPMI
RC_INVALID_VPD_DATA = IPMI_COMP_ID | 0x0e,
RC_INVALID_SENSOR_NUMBER = IPMI_COMP_ID | 0x0f,
RC_INVALID_SENSOR_SETTING = IPMI_COMP_ID | 0x10,
+ RC_GET_DCMI_CAP_CMD_FAILED = IPMI_COMP_ID | 0x11,
};
};
diff --git a/src/include/usr/ipmi/ipmiif.H b/src/include/usr/ipmi/ipmiif.H
index 0421aaef3..68adfa392 100644
--- a/src/include/usr/ipmi/ipmiif.H
+++ b/src/include/usr/ipmi/ipmiif.H
@@ -5,9 +5,10 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2012,2018 */
+/* Contributors Listed Below - COPYRIGHT 2012,2019 */
/* [+] Google Inc. */
/* [+] International Business Machines Corp. */
+/* [+] Maxim Polyakov */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -304,7 +305,10 @@ namespace IPMI
inline const command_t hiomap_event(void)
{ return std::make_pair(NETFUN_IBM, 0x0f); }
- // $TODO RTC:123256 - need to add code to get dcmi capabilities
+ // Used to get dcmi capabilities
+ inline const command_t get_dcmi_capability_info(void)
+ { return std::make_pair(NETFUN_GRPEXT, 0x01); }
+
// This is a dcmi message used to request the
// user defined power limit from the BMC.
inline const command_t get_power_limit(void)
diff --git a/src/usr/ipmiext/ipmidcmi.C b/src/usr/ipmiext/ipmidcmi.C
index 24f192d29..b3f9d1e22 100644
--- a/src/usr/ipmiext/ipmidcmi.C
+++ b/src/usr/ipmiext/ipmidcmi.C
@@ -5,8 +5,9 @@
/* */
/* OpenPOWER HostBoot Project */
/* */
-/* Contributors Listed Below - COPYRIGHT 2015,2018 */
+/* Contributors Listed Below - COPYRIGHT 2015,2019 */
/* [+] International Business Machines Corp. */
+/* [+] Maxim Polyakov */
/* */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
@@ -34,6 +35,8 @@
#include <ipmi/ipmi_reasoncodes.H>
extern trace_desc_t * g_trac_ipmi;
+#define DCMI_CAP_RESPONSE_DATA_LENGTH 7
+
namespace SENSOR
{
enum dcmi_cc
@@ -42,6 +45,107 @@ namespace SENSOR
POWER_LIMIT_NOT_ACTIVE = 0x80,
};
+ static errlHndl_t getPowerManagementSupportStatus(bool &support)
+ {
+ errlHndl_t err = NULL;
+ IPMI::completion_code cc = IPMI::CC_UNKBAD;
+
+ support = false;
+
+ size_t len = 2;
+ uint8_t* data = new uint8_t[len];
+ data[0] = 0xDC; // Group Extension Identification
+ data[1] = 0x01; // Selector - Supported DCMI Capabilities
+
+ err = IPMI::sendrecv(IPMI::get_dcmi_capability_info(), cc, len, data);
+ do
+ {
+ if (err)
+ {
+ TRACFCOMP(g_trac_ipmi,
+ "Failed to send DCMI Capabilities Command to BMC");
+ break;
+ }
+
+ if (cc != IPMI::CC_OK)
+ {
+ TRACFCOMP(g_trac_ipmi,
+ "Get DCMI Capabilities Command: "
+ "bad completion code from BMC=0x%x",
+ cc);
+
+ /*@
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid IPMI::MOD_IPMIDCMI
+ * @reasoncode IPMI::RC_GET_DCMI_CAP_CMD_FAILED
+ * @userdata1 BMC IPMI Completion code.
+ * @devdesc Request to get DCMI Capabilities information
+ * failed
+ * @custdesc The DCMI Capabilities Info Command retrieve
+ * data from the BMC has failed.
+ *
+ */
+
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ IPMI::MOD_IPMIDCMI,
+ IPMI::RC_GET_DCMI_CAP_CMD_FAILED,
+ static_cast<uint64_t>(cc),
+ 0,
+ true);
+ break;
+ }
+
+ if (len != DCMI_CAP_RESPONSE_DATA_LENGTH)
+ {
+ TRACFCOMP(g_trac_ipmi,
+ "Get DCMI Capabilities Command: "
+ "invalid data length=%d",
+ len);
+
+ /*@
+ * @errortype ERRL_SEV_INFORMATIONAL
+ * @moduleid IPMI::MOD_IPMIDCMI
+ * @reasoncode IPMI::RC_INVALID_QRESPONSE
+ * @userdata1 Response data length.
+ * @devdesc Request to get DCMI Capabilities information
+ * failed
+ * @custdesc The DCMI Capabilities Info Command retrieve
+ * data with invalid length.
+ *
+ */
+
+ err = new ERRORLOG::ErrlEntry(
+ ERRORLOG::ERRL_SEV_INFORMATIONAL,
+ IPMI::MOD_IPMIDCMI,
+ IPMI::RC_INVALID_QRESPONSE,
+ static_cast<uint64_t>(len),
+ 0,
+ true);
+ break;
+ }
+
+ // from the DCMI spec v1.5, Revision 1.0, August 23, 2011
+ // DCMI Capabilities Response Command Format:
+ // cc: byte 1 completion code
+ // data:
+ // data[0]: byte 1 0xDC
+ // data[1]: byte 2 Major Version (01h)
+ // data[2]: byte 3 Minor Version (05h)
+ // data[3]: byte 4 Parameter Revision (02h)
+ // data[4]: byte 5 Reserved
+ // data[5]: byte 6 Platform capabilities
+ // [7:1] Reserved
+ // [0] Power management
+ // data[6]: byte 7 Manageability Access Capabilities
+ support = !!(data[5] & 0x1);
+
+ } while(false);
+
+ delete[] data;
+ return err;
+ }
+
// fetch the user defined power limit stored on the BMC
// using the DCMI Get Power Limit command
errlHndl_t getUserPowerLimit( uint16_t &o_powerLimit, bool &o_limitActive )
@@ -53,6 +157,31 @@ namespace SENSOR
errlHndl_t l_err = NULL;
+ // Power Management support check
+ bool support;
+ l_err = getPowerManagementSupportStatus(support);
+ if (l_err != NULL)
+ {
+ // Since the Power Management support information isn`t received,
+ // commit this error and still try to read the power limit. If the
+ // Power Management is really unsupported, the DCMI Get Power Limit
+ // command will return error code in l_cc
+ l_err->collectTrace(IPMI_COMP_NAME);
+ errlCommit(l_err, IPMI_COMP_ID);
+
+ TRACFCOMP(g_trac_ipmi,
+ "Failed to determine if the BMC supports Power Management");
+
+ support = true;
+ }
+
+ if (!support)
+ {
+ TRACFCOMP(g_trac_ipmi,
+ "Power Management is not supported by BMC");
+ return NULL;
+ }
+
// per DCMI spec data size is 3 bytes
size_t len = 3;
OpenPOWER on IntegriCloud