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 ipmbMeTargetAddress = 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 Ipmb frame 104 */ 105 typedef struct 106 { 107 /// @brief IPMB frame header 108 union 109 { 110 /// @brief IPMB request header 111 struct 112 { 113 /** @brief IPMB Connection Header Format */ 114 uint8_t address; 115 uint8_t rsNetFnLUN; 116 uint8_t checksum1; 117 /** @brief IPMB Header */ 118 uint8_t rqSA; 119 uint8_t rqSeqLUN; 120 uint8_t cmd; 121 uint8_t data[]; 122 } Req; 123 /// @brief IPMB response header 124 struct 125 { 126 uint8_t address; 127 /** @brief IPMB Connection Header Format */ 128 uint8_t rqNetFnLUN; 129 uint8_t checksum1; 130 /** @brief IPMB Header */ 131 uint8_t rsSA; 132 uint8_t rsSeqLUN; 133 uint8_t cmd; 134 uint8_t completionCode; 135 uint8_t data[]; 136 } Resp; 137 } Header; 138 } __attribute__((packed)) ipmbHeader; 139 140 /** 141 * @brief Ipmb messages 142 */ 143 struct IpmbRequest 144 { 145 uint8_t address; 146 uint8_t netFn; 147 uint8_t rsLun; 148 uint8_t rqSA; 149 uint8_t seq; 150 uint8_t rqLun; 151 uint8_t cmd; 152 std::vector<uint8_t> data; 153 154 IpmbRequest(const ipmbHeader* ipmbBuffer, size_t bufferLength); 155 156 void prepareRequest(sdbusplus::message_t& mesg); 157 }; 158 159 struct IpmbResponse 160 { 161 uint8_t address; 162 uint8_t netFn; 163 uint8_t rqLun; 164 uint8_t rsSA; 165 uint8_t seq; 166 uint8_t rsLun; 167 uint8_t cmd; 168 uint8_t completionCode; 169 std::vector<uint8_t> data; 170 171 IpmbResponse(uint8_t address, uint8_t netFn, uint8_t rqLun, uint8_t rsSA, 172 uint8_t seq, uint8_t rsLun, uint8_t cmd, 173 uint8_t completionCode, std::vector<uint8_t>& inputData); 174 175 void ipmbToi2cConstruct(uint8_t* buffer, size_t* bufferLength); 176 }; 177 178 /** 179 * @brief Get Message Flags Response 180 */ 181 constexpr uint8_t getMsgFlagReceiveMessageBit = 0; 182 constexpr uint8_t getMsgFlagEventMessageBit = 1; 183 constexpr uint8_t getMsgFlagWatchdogPreTimeOutBit = 3; 184 constexpr uint8_t getMsgFlagOEM0Bit = 5; 185 constexpr uint8_t getMsgFlagOEM1Bit = 6; 186 constexpr uint8_t getMsgFlagOEM2Bit = 7; 187 188 /** @class Bridging 189 * 190 * @brief Implement commands to support IPMI bridging. 191 */ 192 class Bridging 193 { 194 public: 195 Bridging() = default; 196 std::size_t getResponseQueueSize(); 197 198 void clearResponseQueue(); 199 200 ipmi::Cc handleIpmbChannel(ipmi::Context::ptr ctx, const uint8_t tracking, 201 const std::vector<uint8_t>& msgData, 202 std::vector<uint8_t>& rspData); 203 204 void insertMessageInQueue(IpmbResponse msg); 205 206 IpmbResponse getMessageFromQueue(); 207 208 void eraseMessageFromQueue(); 209 210 private: 211 std::vector<IpmbResponse> responseQueue; 212 }; 213