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 */
ipmbNetFnGet(uint8_t netFnLun)37 constexpr uint8_t ipmbNetFnGet(uint8_t netFnLun)
38 {
39 return netFnLun >> 2;
40 }
41
ipmbLunFromNetFnLunGet(uint8_t netFnLun)42 constexpr uint8_t ipmbLunFromNetFnLunGet(uint8_t netFnLun)
43 {
44 return netFnLun & ipmbLunMask;
45 }
46
ipmbSeqGet(uint8_t seqNumLun)47 constexpr uint8_t ipmbSeqGet(uint8_t seqNumLun)
48 {
49 return seqNumLun >> 2;
50 }
51
ipmbLunFromSeqLunGet(uint8_t seqNumLun)52 constexpr uint8_t ipmbLunFromSeqLunGet(uint8_t seqNumLun)
53 {
54 return seqNumLun & ipmbLunMask;
55 }
56
57 /**
58 * @brief Ipmb setters
59 */
ipmbNetFnLunSet(uint8_t netFn,uint8_t lun)60 constexpr uint8_t ipmbNetFnLunSet(uint8_t netFn, uint8_t lun)
61 {
62 return ((netFn << 2) | (lun & ipmbLunMask));
63 }
64
ipmbSeqLunSet(uint8_t seq,uint8_t lun)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 =
78 ipmbConnectionHeaderLength + 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