diff options
author | Saravanan Palanisamy <saravanan.palanisamy@intel.com> | 2019-03-04 18:34:44 +0530 |
---|---|---|
committer | Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com> | 2019-04-09 04:29:26 +0000 |
commit | b5a0f16dca8324492a8b2bd69c82f3438e02fa16 (patch) | |
tree | 8a84afd4d7251ede90f904da045b3657af7124d1 /user_channel/channelcommands.cpp | |
parent | bea5392552b3b6445adf093b97c97512d69db160 (diff) | |
download | phosphor-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.cpp | 109 |
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; } |