blob: bffc76e6d3fa87d0f1ce8b7400a80d746d16a151 [file] [log] [blame]
Vernon Mauerya3702c12019-05-22 13:20:59 -07001/*
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
Vernon Mauery15419dd2019-05-24 09:40:30 -070017#include <ipmid/api.hpp>
Vernon Mauerya3702c12019-05-22 13:20:59 -070018#include <sdbusplus/message.hpp>
19#include <sdbusplus/server/interface.hpp>
20
21/**
22 * @brief Response queue defines
23 */
24constexpr int responseQueueMaxSize = 20;
25
26/**
27 * @brief Ipmb misc
28 */
29constexpr uint8_t ipmbLunMask = 0x03;
30constexpr uint8_t ipmbSeqMask = 0x3F;
31constexpr uint8_t ipmbMeSlaveAddress = 0x2C;
32constexpr uint8_t ipmbMeChannelNum = 1;
33
34/**
35 * @brief Ipmb getters
36 */
37constexpr uint8_t ipmbNetFnGet(uint8_t netFnLun)
38{
39 return netFnLun >> 2;
40}
41
42constexpr uint8_t ipmbLunFromNetFnLunGet(uint8_t netFnLun)
43{
44 return netFnLun & ipmbLunMask;
45}
46
47constexpr uint8_t ipmbSeqGet(uint8_t seqNumLun)
48{
49 return seqNumLun >> 2;
50}
51
52constexpr uint8_t ipmbLunFromSeqLunGet(uint8_t seqNumLun)
53{
54 return seqNumLun & ipmbLunMask;
55}
56
57/**
58 * @brief Ipmb setters
59 */
60constexpr uint8_t ipmbNetFnLunSet(uint8_t netFn, uint8_t lun)
61{
62 return ((netFn << 2) | (lun & ipmbLunMask));
63}
64
65constexpr uint8_t ipmbSeqLunSet(uint8_t seq, uint8_t lun)
66{
67 return ((seq << 2) | (lun & ipmbLunMask));
68}
69
70constexpr size_t ipmbMaxDataSize = 256;
71constexpr size_t ipmbConnectionHeaderLength = 3;
72constexpr size_t ipmbResponseDataHeaderLength = 4;
73constexpr size_t ipmbRequestDataHeaderLength = 3;
74constexpr size_t ipmbChecksum2StartOffset = 3;
75constexpr size_t ipmbChecksumSize = 1;
76constexpr size_t ipmbMinFrameLength = 7;
77constexpr size_t ipmbMaxFrameLength = ipmbConnectionHeaderLength +
78 ipmbResponseDataHeaderLength +
79 ipmbChecksumSize + ipmbMaxDataSize;
80
81/**
82 * @brief Channel types
83 */
84constexpr uint8_t targetChannelIpmb = 0x1;
85constexpr uint8_t targetChannelIcmb10 = 0x2;
86constexpr uint8_t targetChannelIcmb09 = 0x3;
87constexpr uint8_t targetChannelLan = 0x4;
88constexpr uint8_t targetChannelSerialModem = 0x5;
89constexpr uint8_t targetChannelOtherLan = 0x6;
90constexpr uint8_t targetChannelPciSmbus = 0x7;
91constexpr uint8_t targetChannelSmbus10 = 0x8;
92constexpr uint8_t targetChannelSmbus20 = 0x9;
93constexpr uint8_t targetChannelSystemInterface = 0xC;
94
95/**
96 * @brief Channel modes
97 */
98constexpr uint8_t modeNoTracking = 0x0;
99constexpr uint8_t modeTrackRequest = 0x1;
100constexpr uint8_t modeSendRaw = 0x2;
101
102/**
103 * @brief Command specific codes
104 */
105constexpr ipmi_return_codes ipmiGetMessageCmdDataNotAvailable =
106 static_cast<ipmi_return_codes>(0x80);
107
108/**
109 * @brief Ipmb frame
110 */
111typedef 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 */
149struct 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
165struct 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 */
187typedef 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 */
216typedef 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 */
235typedef struct
236{
237 uint8_t flags;
238
239 constexpr void receiveMessageBitSet(uint8_t value)
240 {
241 flags |= (value & 1);
242 }
243
244 constexpr void eventMessageBitSet(uint8_t value)
245 {
246 flags |= (value & 1) << 1;
247 }
248
249 constexpr void watchdogTimeoutBitSet(uint8_t value)
250 {
251 flags |= (value & 1) << 3;
252 }
253
254 constexpr void oem0BitSet(uint8_t value)
255 {
256 flags |= (value & 1) << 5;
257 }
258
259 constexpr void oem1BitSet(uint8_t value)
260 {
261 flags |= (value & 1) << 6;
262 }
263
264 constexpr void oem2BitSet(uint8_t value)
265 {
266 flags |= (value & 1) << 7;
267 }
268} __attribute__((packed)) sGetMessageFlagsResp;
269
270/**
271 * @brief Clear Message Flags Request
272 */
273typedef struct
274{
275 uint8_t flags;
276
277 constexpr uint8_t receiveMessageBitGet()
278 {
279 return (flags & 0x1);
280 }
281
282 constexpr uint8_t eventMessageBitGet()
283 {
284 return ((flags & 0x2) >> 1);
285 }
286
287 constexpr uint8_t watchdogTimeoutBitGet()
288 {
289 return ((flags & 0x8) >> 3);
290 }
291
292 constexpr uint8_t oem0BitGet()
293 {
294 return ((flags & 0x20) >> 5);
295 }
296
297 constexpr uint8_t oem1BitGet()
298 {
299 return ((flags & 0x40) >> 6);
300 }
301
302 constexpr uint8_t oem2BitGet()
303 {
304 return ((flags & 0x80) >> 7);
305 }
306} __attribute__((packed)) sClearMessageFlagsReq;
307
308/** @class Bridging
309 *
310 * @brief Implement commands to support IPMI bridging.
311 */
312class Bridging
313{
314 public:
Vernon Mauery15419dd2019-05-24 09:40:30 -0700315 Bridging() = default;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700316
317 ipmi_return_codes sendMessageHandler(ipmi_request_t request,
318 ipmi_response_t response,
319 ipmi_data_len_t dataLen);
320
321 ipmi_return_codes getMessageHandler(ipmi_request_t request,
322 ipmi_response_t response,
323 ipmi_data_len_t dataLen);
324
325 ipmi_return_codes clearMessageFlagsHandler(ipmi_request_t request,
326 ipmi_response_t response,
327 ipmi_data_len_t dataLen);
328
329 ipmi_return_codes getMessageFlagsHandler(ipmi_request_t request,
330 ipmi_response_t response,
331 ipmi_data_len_t dataLen);
332
333 enum IpmiAppBridgingCmds
334 {
335 ipmiCmdClearMessageFlags = 0x30,
336 ipmiCmdGetMessageFlags = 0x31,
337 ipmiCmdGetMessage = 0x33,
338 ipmiCmdSendMessage = 0x34,
339 };
340
341 private:
342 std::vector<IpmbResponse> responseQueue;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700343
344 ipmi_return_codes handleIpmbChannel(sSendMessageReq *sendMsgReq,
345 ipmi_response_t response,
346 ipmi_data_len_t dataLen);
347};