blob: e277b58a51300b6e802fea3454d550f7567fb5a2 [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
17#include <sdbusplus/message.hpp>
18#include <sdbusplus/server/interface.hpp>
19
20/**
21 * @brief Response queue defines
22 */
23constexpr int responseQueueMaxSize = 20;
24
25/**
26 * @brief Ipmb misc
27 */
28constexpr uint8_t ipmbLunMask = 0x03;
29constexpr uint8_t ipmbSeqMask = 0x3F;
30constexpr uint8_t ipmbMeSlaveAddress = 0x2C;
31constexpr uint8_t ipmbMeChannelNum = 1;
32
33/**
34 * @brief Ipmb getters
35 */
36constexpr uint8_t ipmbNetFnGet(uint8_t netFnLun)
37{
38 return netFnLun >> 2;
39}
40
41constexpr uint8_t ipmbLunFromNetFnLunGet(uint8_t netFnLun)
42{
43 return netFnLun & ipmbLunMask;
44}
45
46constexpr uint8_t ipmbSeqGet(uint8_t seqNumLun)
47{
48 return seqNumLun >> 2;
49}
50
51constexpr uint8_t ipmbLunFromSeqLunGet(uint8_t seqNumLun)
52{
53 return seqNumLun & ipmbLunMask;
54}
55
56/**
57 * @brief Ipmb setters
58 */
59constexpr uint8_t ipmbNetFnLunSet(uint8_t netFn, uint8_t lun)
60{
61 return ((netFn << 2) | (lun & ipmbLunMask));
62}
63
64constexpr uint8_t ipmbSeqLunSet(uint8_t seq, uint8_t lun)
65{
66 return ((seq << 2) | (lun & ipmbLunMask));
67}
68
69constexpr size_t ipmbMaxDataSize = 256;
70constexpr size_t ipmbConnectionHeaderLength = 3;
71constexpr size_t ipmbResponseDataHeaderLength = 4;
72constexpr size_t ipmbRequestDataHeaderLength = 3;
73constexpr size_t ipmbChecksum2StartOffset = 3;
74constexpr size_t ipmbChecksumSize = 1;
75constexpr size_t ipmbMinFrameLength = 7;
76constexpr size_t ipmbMaxFrameLength = ipmbConnectionHeaderLength +
77 ipmbResponseDataHeaderLength +
78 ipmbChecksumSize + ipmbMaxDataSize;
79
80/**
81 * @brief Channel types
82 */
83constexpr uint8_t targetChannelIpmb = 0x1;
84constexpr uint8_t targetChannelIcmb10 = 0x2;
85constexpr uint8_t targetChannelIcmb09 = 0x3;
86constexpr uint8_t targetChannelLan = 0x4;
87constexpr uint8_t targetChannelSerialModem = 0x5;
88constexpr uint8_t targetChannelOtherLan = 0x6;
89constexpr uint8_t targetChannelPciSmbus = 0x7;
90constexpr uint8_t targetChannelSmbus10 = 0x8;
91constexpr uint8_t targetChannelSmbus20 = 0x9;
92constexpr uint8_t targetChannelSystemInterface = 0xC;
93
94/**
95 * @brief Channel modes
96 */
97constexpr uint8_t modeNoTracking = 0x0;
98constexpr uint8_t modeTrackRequest = 0x1;
99constexpr uint8_t modeSendRaw = 0x2;
100
101/**
102 * @brief Command specific codes
103 */
104constexpr ipmi_return_codes ipmiGetMessageCmdDataNotAvailable =
105 static_cast<ipmi_return_codes>(0x80);
106
107/**
108 * @brief Ipmb frame
109 */
110typedef struct
111{
112 /// @brief IPMB frame header
113 union
114 {
115 /// @brief IPMB request header
116 struct
117 {
118 /** @brief IPMB Connection Header Format */
119 uint8_t address;
120 uint8_t rsNetFnLUN;
121 uint8_t checksum1;
122 /** @brief IPMB Header */
123 uint8_t rqSA;
124 uint8_t rqSeqLUN;
125 uint8_t cmd;
126 uint8_t data[];
127 } Req;
128 /// @brief IPMB response header
129 struct
130 {
131 uint8_t address;
132 /** @brief IPMB Connection Header Format */
133 uint8_t rqNetFnLUN;
134 uint8_t checksum1;
135 /** @brief IPMB Header */
136 uint8_t rsSA;
137 uint8_t rsSeqLUN;
138 uint8_t cmd;
139 uint8_t completionCode;
140 uint8_t data[];
141 } Resp;
142 } Header;
143} __attribute__((packed)) ipmbHeader;
144
145/**
146 * @brief Ipmb messages
147 */
148struct IpmbRequest
149{
150 uint8_t address;
151 uint8_t netFn;
152 uint8_t rsLun;
153 uint8_t rqSA;
154 uint8_t seq;
155 uint8_t rqLun;
156 uint8_t cmd;
157 std::vector<uint8_t> data;
158
159 IpmbRequest(const ipmbHeader *ipmbBuffer, size_t bufferLength);
160
161 void prepareRequest(sdbusplus::message::message &mesg);
162};
163
164struct IpmbResponse
165{
166 uint8_t address;
167 uint8_t netFn;
168 uint8_t rqLun;
169 uint8_t rsSA;
170 uint8_t seq;
171 uint8_t rsLun;
172 uint8_t cmd;
173 uint8_t completionCode;
174 std::vector<uint8_t> data;
175
176 IpmbResponse(uint8_t address, uint8_t netFn, uint8_t rqLun, uint8_t rsSA,
177 uint8_t seq, uint8_t rsLun, uint8_t cmd,
178 uint8_t completionCode, std::vector<uint8_t> &inputData);
179
180 void ipmbToi2cConstruct(uint8_t *buffer, size_t *bufferLength);
181};
182
183/**
184 * @brief Send Message Request
185 */
186typedef struct
187{
188 uint8_t channelData;
189 uint8_t data[];
190
191 constexpr uint8_t channelNumGet()
192 {
193 return (channelData & 0xF);
194 }
195
196 constexpr uint8_t authenticationGet()
197 {
198 return ((channelData & 0x10) >> 4);
199 }
200
201 constexpr uint8_t encryptionGet()
202 {
203 return ((channelData & 0x20) >> 5);
204 }
205
206 constexpr uint8_t modeGet()
207 {
208 return ((channelData & 0xC0) >> 6);
209 }
210} __attribute__((packed)) sSendMessageReq;
211
212/**
213 * @brief Get Message Response
214 */
215typedef struct
216{
217 uint8_t channelData;
218 uint8_t data[];
219
220 constexpr void channelNumSet(uint8_t num)
221 {
222 channelData |= num & 0xF;
223 }
224
225 constexpr void privilegeLvlSet(CommandPrivilege privLvl)
226 {
227 channelData |= static_cast<uint8_t>(privLvl) & 0xF0;
228 }
229} __attribute__((packed)) sGetMessageRes;
230
231/**
232 * @brief Get Message Flags Response
233 */
234typedef struct
235{
236 uint8_t flags;
237
238 constexpr void receiveMessageBitSet(uint8_t value)
239 {
240 flags |= (value & 1);
241 }
242
243 constexpr void eventMessageBitSet(uint8_t value)
244 {
245 flags |= (value & 1) << 1;
246 }
247
248 constexpr void watchdogTimeoutBitSet(uint8_t value)
249 {
250 flags |= (value & 1) << 3;
251 }
252
253 constexpr void oem0BitSet(uint8_t value)
254 {
255 flags |= (value & 1) << 5;
256 }
257
258 constexpr void oem1BitSet(uint8_t value)
259 {
260 flags |= (value & 1) << 6;
261 }
262
263 constexpr void oem2BitSet(uint8_t value)
264 {
265 flags |= (value & 1) << 7;
266 }
267} __attribute__((packed)) sGetMessageFlagsResp;
268
269/**
270 * @brief Clear Message Flags Request
271 */
272typedef struct
273{
274 uint8_t flags;
275
276 constexpr uint8_t receiveMessageBitGet()
277 {
278 return (flags & 0x1);
279 }
280
281 constexpr uint8_t eventMessageBitGet()
282 {
283 return ((flags & 0x2) >> 1);
284 }
285
286 constexpr uint8_t watchdogTimeoutBitGet()
287 {
288 return ((flags & 0x8) >> 3);
289 }
290
291 constexpr uint8_t oem0BitGet()
292 {
293 return ((flags & 0x20) >> 5);
294 }
295
296 constexpr uint8_t oem1BitGet()
297 {
298 return ((flags & 0x40) >> 6);
299 }
300
301 constexpr uint8_t oem2BitGet()
302 {
303 return ((flags & 0x80) >> 7);
304 }
305} __attribute__((packed)) sClearMessageFlagsReq;
306
307/** @class Bridging
308 *
309 * @brief Implement commands to support IPMI bridging.
310 */
311class Bridging
312{
313 public:
314 Bridging();
315
316 ipmi_return_codes sendMessageHandler(ipmi_request_t request,
317 ipmi_response_t response,
318 ipmi_data_len_t dataLen);
319
320 ipmi_return_codes getMessageHandler(ipmi_request_t request,
321 ipmi_response_t response,
322 ipmi_data_len_t dataLen);
323
324 ipmi_return_codes clearMessageFlagsHandler(ipmi_request_t request,
325 ipmi_response_t response,
326 ipmi_data_len_t dataLen);
327
328 ipmi_return_codes getMessageFlagsHandler(ipmi_request_t request,
329 ipmi_response_t response,
330 ipmi_data_len_t dataLen);
331
332 enum IpmiAppBridgingCmds
333 {
334 ipmiCmdClearMessageFlags = 0x30,
335 ipmiCmdGetMessageFlags = 0x31,
336 ipmiCmdGetMessage = 0x33,
337 ipmiCmdSendMessage = 0x34,
338 };
339
340 private:
341 std::vector<IpmbResponse> responseQueue;
342 sdbusplus::bus::bus dbus;
343
344 ipmi_return_codes handleIpmbChannel(sSendMessageReq *sendMsgReq,
345 ipmi_response_t response,
346 ipmi_data_len_t dataLen);
347};