1 /* 2 // Copyright (c) 2018 Intel Corporation 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 */ 16 #pragma once 17 #include <ipmid/api.hpp> 18 #include <sdbusplus/message.hpp> 19 #include <sdbusplus/server/interface.hpp> 20 21 /** 22 * @brief Response queue defines 23 */ 24 constexpr int responseQueueMaxSize = 20; 25 26 /** 27 * @brief Ipmb misc 28 */ 29 constexpr uint8_t ipmbLunMask = 0x03; 30 constexpr uint8_t ipmbSeqMask = 0x3F; 31 constexpr uint8_t ipmbMeSlaveAddress = 0x2C; 32 constexpr uint8_t ipmbMeChannelNum = 1; 33 34 /** 35 * @brief Ipmb getters 36 */ 37 constexpr uint8_t ipmbNetFnGet(uint8_t netFnLun) 38 { 39 return netFnLun >> 2; 40 } 41 42 constexpr uint8_t ipmbLunFromNetFnLunGet(uint8_t netFnLun) 43 { 44 return netFnLun & ipmbLunMask; 45 } 46 47 constexpr uint8_t ipmbSeqGet(uint8_t seqNumLun) 48 { 49 return seqNumLun >> 2; 50 } 51 52 constexpr uint8_t ipmbLunFromSeqLunGet(uint8_t seqNumLun) 53 { 54 return seqNumLun & ipmbLunMask; 55 } 56 57 /** 58 * @brief Ipmb setters 59 */ 60 constexpr uint8_t ipmbNetFnLunSet(uint8_t netFn, uint8_t lun) 61 { 62 return ((netFn << 2) | (lun & ipmbLunMask)); 63 } 64 65 constexpr uint8_t ipmbSeqLunSet(uint8_t seq, uint8_t lun) 66 { 67 return ((seq << 2) | (lun & ipmbLunMask)); 68 } 69 70 constexpr size_t ipmbMaxDataSize = 256; 71 constexpr size_t ipmbConnectionHeaderLength = 3; 72 constexpr size_t ipmbResponseDataHeaderLength = 4; 73 constexpr size_t ipmbRequestDataHeaderLength = 3; 74 constexpr size_t ipmbChecksum2StartOffset = 3; 75 constexpr size_t ipmbChecksumSize = 1; 76 constexpr size_t ipmbMinFrameLength = 7; 77 constexpr size_t ipmbMaxFrameLength = ipmbConnectionHeaderLength + 78 ipmbResponseDataHeaderLength + 79 ipmbChecksumSize + ipmbMaxDataSize; 80 81 /** 82 * @brief Channel types 83 */ 84 constexpr uint8_t targetChannelIpmb = 0x1; 85 constexpr uint8_t targetChannelIcmb10 = 0x2; 86 constexpr uint8_t targetChannelIcmb09 = 0x3; 87 constexpr uint8_t targetChannelLan = 0x4; 88 constexpr uint8_t targetChannelSerialModem = 0x5; 89 constexpr uint8_t targetChannelOtherLan = 0x6; 90 constexpr uint8_t targetChannelPciSmbus = 0x7; 91 constexpr uint8_t targetChannelSmbus10 = 0x8; 92 constexpr uint8_t targetChannelSmbus20 = 0x9; 93 constexpr uint8_t targetChannelSystemInterface = 0xC; 94 95 /** 96 * @brief Channel modes 97 */ 98 constexpr uint8_t modeNoTracking = 0x0; 99 constexpr uint8_t modeTrackRequest = 0x1; 100 constexpr uint8_t modeSendRaw = 0x2; 101 102 /** 103 * @brief Command specific codes 104 */ 105 constexpr ipmi_return_codes ipmiGetMessageCmdDataNotAvailable = 106 static_cast<ipmi_return_codes>(0x80); 107 108 /** 109 * @brief Ipmb frame 110 */ 111 typedef struct 112 { 113 /// @brief IPMB frame header 114 union 115 { 116 /// @brief IPMB request header 117 struct 118 { 119 /** @brief IPMB Connection Header Format */ 120 uint8_t address; 121 uint8_t rsNetFnLUN; 122 uint8_t checksum1; 123 /** @brief IPMB Header */ 124 uint8_t rqSA; 125 uint8_t rqSeqLUN; 126 uint8_t cmd; 127 uint8_t data[]; 128 } Req; 129 /// @brief IPMB response header 130 struct 131 { 132 uint8_t address; 133 /** @brief IPMB Connection Header Format */ 134 uint8_t rqNetFnLUN; 135 uint8_t checksum1; 136 /** @brief IPMB Header */ 137 uint8_t rsSA; 138 uint8_t rsSeqLUN; 139 uint8_t cmd; 140 uint8_t completionCode; 141 uint8_t data[]; 142 } Resp; 143 } Header; 144 } __attribute__((packed)) ipmbHeader; 145 146 /** 147 * @brief Ipmb messages 148 */ 149 struct IpmbRequest 150 { 151 uint8_t address; 152 uint8_t netFn; 153 uint8_t rsLun; 154 uint8_t rqSA; 155 uint8_t seq; 156 uint8_t rqLun; 157 uint8_t cmd; 158 std::vector<uint8_t> data; 159 160 IpmbRequest(const ipmbHeader *ipmbBuffer, size_t bufferLength); 161 162 void prepareRequest(sdbusplus::message::message &mesg); 163 }; 164 165 struct IpmbResponse 166 { 167 uint8_t address; 168 uint8_t netFn; 169 uint8_t rqLun; 170 uint8_t rsSA; 171 uint8_t seq; 172 uint8_t rsLun; 173 uint8_t cmd; 174 uint8_t completionCode; 175 std::vector<uint8_t> data; 176 177 IpmbResponse(uint8_t address, uint8_t netFn, uint8_t rqLun, uint8_t rsSA, 178 uint8_t seq, uint8_t rsLun, uint8_t cmd, 179 uint8_t completionCode, std::vector<uint8_t> &inputData); 180 181 void ipmbToi2cConstruct(uint8_t *buffer, size_t *bufferLength); 182 }; 183 184 /** 185 * @brief Send Message Request 186 */ 187 typedef struct 188 { 189 uint8_t channelData; 190 uint8_t data[]; 191 192 constexpr uint8_t channelNumGet() 193 { 194 return (channelData & 0xF); 195 } 196 197 constexpr uint8_t authenticationGet() 198 { 199 return ((channelData & 0x10) >> 4); 200 } 201 202 constexpr uint8_t encryptionGet() 203 { 204 return ((channelData & 0x20) >> 5); 205 } 206 207 constexpr uint8_t modeGet() 208 { 209 return ((channelData & 0xC0) >> 6); 210 } 211 } __attribute__((packed)) sSendMessageReq; 212 213 /** 214 * @brief Get Message Response 215 */ 216 typedef struct 217 { 218 uint8_t channelData; 219 uint8_t data[]; 220 221 constexpr void channelNumSet(uint8_t num) 222 { 223 channelData |= num & 0xF; 224 } 225 226 constexpr void privilegeLvlSet(CommandPrivilege privLvl) 227 { 228 channelData |= static_cast<uint8_t>(privLvl) & 0xF0; 229 } 230 } __attribute__((packed)) sGetMessageRes; 231 232 /** 233 * @brief Get Message Flags Response 234 */ 235 constexpr uint8_t getMsgFlagReceiveMessageBit = 0; 236 constexpr uint8_t getMsgFlagEventMessageBit = 1; 237 constexpr uint8_t getMsgFlagWatchdogPreTimeOutBit = 3; 238 constexpr uint8_t getMsgFlagOEM0Bit = 5; 239 constexpr uint8_t getMsgFlagOEM1Bit = 6; 240 constexpr uint8_t getMsgFlagOEM2Bit = 7; 241 242 /** 243 * @brief Clear Message Flags Request 244 */ 245 typedef struct 246 { 247 uint8_t flags; 248 249 constexpr uint8_t receiveMessageBitGet() 250 { 251 return (flags & 0x1); 252 } 253 254 constexpr uint8_t eventMessageBitGet() 255 { 256 return ((flags & 0x2) >> 1); 257 } 258 259 constexpr uint8_t watchdogTimeoutBitGet() 260 { 261 return ((flags & 0x8) >> 3); 262 } 263 264 constexpr uint8_t oem0BitGet() 265 { 266 return ((flags & 0x20) >> 5); 267 } 268 269 constexpr uint8_t oem1BitGet() 270 { 271 return ((flags & 0x40) >> 6); 272 } 273 274 constexpr uint8_t oem2BitGet() 275 { 276 return ((flags & 0x80) >> 7); 277 } 278 } __attribute__((packed)) sClearMessageFlagsReq; 279 280 /** @class Bridging 281 * 282 * @brief Implement commands to support IPMI bridging. 283 */ 284 class Bridging 285 { 286 public: 287 Bridging() = default; 288 std::size_t getResponseQueueSize(); 289 290 ipmi_return_codes sendMessageHandler(ipmi_request_t request, 291 ipmi_response_t response, 292 ipmi_data_len_t dataLen); 293 294 ipmi_return_codes getMessageHandler(ipmi_request_t request, 295 ipmi_response_t response, 296 ipmi_data_len_t dataLen); 297 298 ipmi_return_codes clearMessageFlagsHandler(ipmi_request_t request, 299 ipmi_response_t response, 300 ipmi_data_len_t dataLen); 301 302 enum IpmiAppBridgingCmds 303 { 304 ipmiCmdClearMessageFlags = 0x30, 305 ipmiCmdGetMessage = 0x33, 306 ipmiCmdSendMessage = 0x34, 307 }; 308 309 private: 310 std::vector<IpmbResponse> responseQueue; 311 312 ipmi_return_codes handleIpmbChannel(sSendMessageReq *sendMsgReq, 313 ipmi_response_t response, 314 ipmi_data_len_t dataLen); 315 }; 316