blob: fe92f6cb1bf12edede8c8afdba2b749f8c37a462 [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 */
Yong Lic3580e92019-08-15 14:36:47 +0800235constexpr uint8_t getMsgFlagReceiveMessageBit = 0;
236constexpr uint8_t getMsgFlagEventMessageBit = 1;
237constexpr uint8_t getMsgFlagWatchdogPreTimeOutBit = 3;
238constexpr uint8_t getMsgFlagOEM0Bit = 5;
239constexpr uint8_t getMsgFlagOEM1Bit = 6;
240constexpr uint8_t getMsgFlagOEM2Bit = 7;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700241
242/**
243 * @brief Clear Message Flags Request
244 */
245typedef 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 */
284class Bridging
285{
286 public:
Vernon Mauery15419dd2019-05-24 09:40:30 -0700287 Bridging() = default;
Yong Lic3580e92019-08-15 14:36:47 +0800288 std::size_t getResponseQueueSize();
Vernon Mauerya3702c12019-05-22 13:20:59 -0700289
jayaprakash Mutyala405f54a2019-10-18 18:23:27 +0000290 std::vector<IpmbResponse> getResponseQueue();
291 void clearResponseQueue();
292
Vernon Mauerya3702c12019-05-22 13:20:59 -0700293 ipmi_return_codes sendMessageHandler(ipmi_request_t request,
294 ipmi_response_t response,
295 ipmi_data_len_t dataLen);
296
297 ipmi_return_codes getMessageHandler(ipmi_request_t request,
298 ipmi_response_t response,
299 ipmi_data_len_t dataLen);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700300 enum IpmiAppBridgingCmds
301 {
Vernon Mauerya3702c12019-05-22 13:20:59 -0700302 ipmiCmdGetMessage = 0x33,
303 ipmiCmdSendMessage = 0x34,
304 };
305
306 private:
307 std::vector<IpmbResponse> responseQueue;
Vernon Mauerya3702c12019-05-22 13:20:59 -0700308
309 ipmi_return_codes handleIpmbChannel(sSendMessageReq *sendMsgReq,
310 ipmi_response_t response,
311 ipmi_data_len_t dataLen);
312};