summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSaravanan Palanisamy <saravanan.palanisamy@intel.com>2019-03-04 18:34:44 +0530
committerRichard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>2019-04-09 04:29:26 +0000
commitb5a0f16dca8324492a8b2bd69c82f3438e02fa16 (patch)
tree8a84afd4d7251ede90f904da045b3657af7124d1
parentbea5392552b3b6445adf093b97c97512d69db160 (diff)
downloadphosphor-host-ipmid-b5a0f16dca8324492a8b2bd69c82f3438e02fa16.zip
phosphor-host-ipmid-b5a0f16dca8324492a8b2bd69c82f3438e02fa16.tar.gz
Add: Get channel payload support command
Implemented Get Channel Payload Support command (IPMI Spec sec 24.8) The same is implemented under channel commands, and will be available for both Host & Net ipmid. Uses channel configuration to differentiate between session / session-less channel Tested-by: 1. Verified command executed successfully for session based channel ipmitool raw 6 0x4E 0x1 // Command 03 00 15 00 00 00 00 00 // Response 2. Verified sessionless channel error is returned. Change-Id: I8b294234415b4467aeae6c23c192750471536f4e Signed-off-by: Saravanan Palanisamy <saravanan.palanisamy@intel.com> Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com>
-rw-r--r--host-ipmid-whitelist.conf1
-rw-r--r--user_channel/channel_layer.hpp18
-rw-r--r--user_channel/channelcommands.cpp109
-rw-r--r--user_channel/channelcommands.hpp1
4 files changed, 129 insertions, 0 deletions
diff --git a/host-ipmid-whitelist.conf b/host-ipmid-whitelist.conf
index 7ac432c..961214d 100644
--- a/host-ipmid-whitelist.conf
+++ b/host-ipmid-whitelist.conf
@@ -26,6 +26,7 @@
0x06:0x36 //<App>:<Get BT Interface Capabilities>
0x06:0x37 //<App>:<Get System GUID>
0x06:0x42 //<App>:<Get Channel Info Command>
+0x06:0x4E //<App>:<Get Channel Payload Support>
0x06:0x54 //<App>:<Get Channel Cipher Suites>
0x0A:0x10 //<Storage>:<Get FRU Inventory Area Info>
0x0A:0x11 //<Storage>:<Read FRU Data>
diff --git a/user_channel/channel_layer.hpp b/user_channel/channel_layer.hpp
index 94570fb..1a8d64c 100644
--- a/user_channel/channel_layer.hpp
+++ b/user_channel/channel_layer.hpp
@@ -112,6 +112,24 @@ enum class EAuthType : uint8_t
oem = (1 << 0x5),
};
+// TODO: Remove duplicate 'PayloadType' definition from netipmid's message.hpp
+// to phosphor-ipmi-host/include
+/**
+ * @enum Payload Types (refer spec sec 13.27.3)
+ */
+enum class PayloadType : uint8_t
+{
+ IPMI = 0x00,
+ SOL = 0x01,
+ OPEN_SESSION_REQUEST = 0x10,
+ OPEN_SESSION_RESPONSE = 0x11,
+ RAKP1 = 0x12,
+ RAKP2 = 0x13,
+ RAKP3 = 0x14,
+ RAKP4 = 0x15,
+ INVALID = 0xFF,
+};
+
/**
* @enum Access mode for channel access set/get (refer spec
* sec 22.22 - request byte 2[7:6])
diff --git a/user_channel/channelcommands.cpp b/user_channel/channelcommands.cpp
index 546adb0..d1b275e 100644
--- a/user_channel/channelcommands.cpp
+++ b/user_channel/channelcommands.cpp
@@ -152,6 +152,36 @@ struct GetChannelInfoResp
uint8_t auxChInfo[2];
} __attribute__((packed));
+/** @struct GetChannelPayloadSupportReq
+ *
+ * Structure for get channel payload support command request (refer spec
+ * sec 24.8)
+ */
+struct GetChannelPayloadSupportReq
+{
+#if BYTE_ORDER == LITTLE_ENDIAN
+ uint8_t chNum : 4;
+ uint8_t reserved : 4;
+#endif
+#if BYTE_ORDER == BIG_ENDIAN
+ uint8_t reserved : 4;
+ uint8_t chNum : 4;
+#endif
+} __attribute__((packed));
+
+/** @struct GetChannelPayloadSupportResp
+ *
+ * Structure for get channel payload support command response (refer spec
+ * sec 24.8)
+ */
+struct GetChannelPayloadSupportResp
+{
+ uint8_t stdPayloadType[2];
+ uint8_t sessSetupPayloadType[2];
+ uint8_t OEMPayloadType[2];
+ uint8_t reserved[2];
+} __attribute__((packed));
+
ipmi_ret_t ipmiSetChannelAccess(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
ipmi_request_t request,
ipmi_response_t response,
@@ -390,6 +420,81 @@ ipmi_ret_t ipmiGetChannelInfo(ipmi_netfn_t netfn, ipmi_cmd_t cmd,
return IPMI_CC_OK;
}
+ipmi_ret_t ipmiGetChannelPayloadSupport(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)
+{
+ const auto req = static_cast<GetChannelPayloadSupportReq*>(request);
+ size_t reqLength = *data_len;
+
+ *data_len = 0;
+
+ if (reqLength != sizeof(*req))
+ {
+ log<level::DEBUG>("Get channel payload - Invalid Length");
+ return IPMI_CC_REQ_DATA_LEN_INVALID;
+ }
+
+ uint8_t chNum = convertCurrentChannelNum(req->chNum);
+ if (!isValidChannel(chNum) || req->reserved != 0)
+ {
+ log<level::DEBUG>("Get channel payload - Invalid field in request");
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ // Not supported on sessionless channels.
+ if (EChannelSessSupported::none == getChannelSessionSupport(chNum))
+ {
+ log<level::DEBUG>("Get channel payload - Sessionless Channel");
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ // Session support is available in active LAN channels.
+ if ((EChannelSessSupported::none != getChannelSessionSupport(chNum)) &&
+ (!(doesDeviceExist(chNum))))
+ {
+ log<level::DEBUG>("Get channel payload - Device not exist");
+ return IPMI_CC_INVALID_FIELD_REQUEST;
+ }
+
+ auto resp = static_cast<GetChannelPayloadSupportResp*>(response);
+
+ std::fill(reinterpret_cast<uint8_t*>(resp),
+ reinterpret_cast<uint8_t*>(resp) + sizeof(*resp), 0);
+
+ // TODO: Hard coding for now.
+ // Mapping PayloadTypes to 'GetChannelPayloadSupportResp' fields:
+ // --------------------------------------------------------------
+ // Mask all except least 3 significant bits to get a value in the range of
+ // 0-7. This value maps to the bit position of given payload type in 'resp'
+ // fields.
+
+ static constexpr uint8_t payloadByteMask = 0x07;
+ static constexpr uint8_t stdPayloadTypeIPMI =
+ 1 << (static_cast<uint8_t>(PayloadType::IPMI) & payloadByteMask);
+ static constexpr uint8_t stdPayloadTypeSOL =
+ 1 << (static_cast<uint8_t>(PayloadType::SOL) & payloadByteMask);
+
+ static constexpr uint8_t sessPayloadTypeOpenReq =
+ 1 << (static_cast<uint8_t>(PayloadType::OPEN_SESSION_REQUEST) &
+ payloadByteMask);
+ static constexpr uint8_t sessPayloadTypeRAKP1 =
+ 1 << (static_cast<uint8_t>(PayloadType::RAKP1) & payloadByteMask);
+ static constexpr uint8_t sessPayloadTypeRAKP3 =
+ 1 << (static_cast<uint8_t>(PayloadType::RAKP3) & payloadByteMask);
+
+ resp->stdPayloadType[0] = stdPayloadTypeIPMI | stdPayloadTypeSOL;
+ // RMCP+ Open Session request, RAKP Message1 and RAKP Message3.
+ resp->sessSetupPayloadType[0] =
+ sessPayloadTypeOpenReq | sessPayloadTypeRAKP1 | sessPayloadTypeRAKP3;
+
+ *data_len = sizeof(*resp);
+
+ return IPMI_CC_OK;
+}
+
void registerChannelFunctions() __attribute__((constructor));
void registerChannelFunctions()
{
@@ -403,6 +508,10 @@ void registerChannelFunctions()
ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_INFO, NULL,
ipmiGetChannelInfo, PRIVILEGE_USER);
+
+ ipmi_register_callback(NETFUN_APP, IPMI_CMD_GET_CHANNEL_PAYLOAD_SUPPORT,
+ NULL, ipmiGetChannelPayloadSupport, PRIVILEGE_USER);
+
return;
}
diff --git a/user_channel/channelcommands.hpp b/user_channel/channelcommands.hpp
index c612d3f..abcead6 100644
--- a/user_channel/channelcommands.hpp
+++ b/user_channel/channelcommands.hpp
@@ -28,6 +28,7 @@ enum ipmi_netfn_channel_cmds
IPMI_CMD_SET_CHANNEL_ACCESS = 0x40,
IPMI_CMD_GET_CHANNEL_ACCESS = 0x41,
IPMI_CMD_GET_CHANNEL_INFO = 0x42,
+ IPMI_CMD_GET_CHANNEL_PAYLOAD_SUPPORT = 0x4E,
};
void registerChannelFunctions();
OpenPOWER on IntegriCloud