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 = 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