summaryrefslogtreecommitdiffstats
path: root/user_channel/channelcommands.cpp
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 /user_channel/channelcommands.cpp
parentbea5392552b3b6445adf093b97c97512d69db160 (diff)
downloadphosphor-host-ipmid-b5a0f16dca8324492a8b2bd69c82f3438e02fa16.tar.gz
phosphor-host-ipmid-b5a0f16dca8324492a8b2bd69c82f3438e02fa16.zip
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>
Diffstat (limited to 'user_channel/channelcommands.cpp')
-rw-r--r--user_channel/channelcommands.cpp109
1 files changed, 109 insertions, 0 deletions
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;
}
OpenPOWER on IntegriCloud