blob: adf19d542fc47289d8b942dbed87c16c54654234 [file] [log] [blame]
AppaRao Puli071f3f22018-05-24 16:45:30 +05301/*
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
AppaRao Puli071f3f22018-05-24 16:45:30 +053017#include "apphandler.hpp"
18#include "channel_layer.hpp"
19
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000020#include <ipmid/api.hpp>
AppaRao Puli071f3f22018-05-24 16:45:30 +053021#include <phosphor-logging/log.hpp>
22#include <regex>
23
24using namespace phosphor::logging;
25
26namespace ipmi
27{
28
anil kumar appanaddb1f442019-07-04 18:07:27 +000029static constexpr const uint8_t ccActionNotSupportedForChannel = 0x82;
30
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000031/** @brief implements the set channel access command
32 * @ param ctx - context pointer
33 * @ param channel - channel number
34 * @ param reserved - skip 4 bits
35 * @ param accessMode - access mode for IPMI messaging
36 * @ param usrAuth - user level authentication (enable/disable)
37 * @ param msgAuth - per message authentication (enable/disable)
38 * @ param alertDisabled - PEF alerting (enable/disable)
39 * @ param chanAccess - channel access
40 * @ param channelPrivLimit - channel privilege limit
41 * @ param reserved - skip 3 bits
42 * @ param channelPrivMode - channel priviledge mode
43 *
44 * @ returns IPMI completion code
45 **/
46RspType<> ipmiSetChannelAccess(Context::ptr ctx, uint4_t channel,
47 uint4_t reserved1, uint3_t accessMode,
48 bool usrAuth, bool msgAuth, bool alertDisabled,
49 uint2_t chanAccess, uint4_t channelPrivLimit,
50 uint2_t reserved2, uint2_t channelPrivMode)
AppaRao Puli071f3f22018-05-24 16:45:30 +053051{
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000052 const uint8_t chNum =
53 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
AppaRao Puli071f3f22018-05-24 16:45:30 +053054
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000055 if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +053056 {
Richard Marian Thomaiyaref024012019-01-29 11:06:39 +053057 log<level::DEBUG>("Set channel access - Invalid field in request");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000058 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +053059 }
60
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000061 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
AppaRao Puli071f3f22018-05-24 16:45:30 +053062 {
63 log<level::DEBUG>("Set channel access - No support on channel");
anil kumar appanaddb1f442019-07-04 18:07:27 +000064 return response(ccActionNotSupportedForChannel);
AppaRao Puli071f3f22018-05-24 16:45:30 +053065 }
66
67 ChannelAccess chActData;
68 ChannelAccess chNVData;
69 uint8_t setActFlag = 0;
70 uint8_t setNVFlag = 0;
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000071 Cc compCode;
AppaRao Puli071f3f22018-05-24 16:45:30 +053072
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000073 // cannot static cast directly from uint2_t to enum; must go via int
74 uint8_t channelAccessAction = static_cast<uint8_t>(chanAccess);
75 switch (static_cast<EChannelActionType>(channelAccessAction))
AppaRao Puli071f3f22018-05-24 16:45:30 +053076 {
77 case doNotSet:
AppaRao Puli071f3f22018-05-24 16:45:30 +053078 break;
79 case nvData:
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000080 chNVData.accessMode = static_cast<uint8_t>(accessMode);
81 chNVData.userAuthDisabled = usrAuth;
82 chNVData.perMsgAuthDisabled = msgAuth;
83 chNVData.alertingDisabled = alertDisabled;
AppaRao Puli071f3f22018-05-24 16:45:30 +053084 setNVFlag |= (setAccessMode | setUserAuthEnabled |
85 setMsgAuthEnabled | setAlertingEnabled);
86 break;
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000087
AppaRao Puli071f3f22018-05-24 16:45:30 +053088 case activeData:
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000089 chActData.accessMode = static_cast<uint8_t>(accessMode);
90 chActData.userAuthDisabled = usrAuth;
91 chActData.perMsgAuthDisabled = msgAuth;
92 chActData.alertingDisabled = alertDisabled;
AppaRao Puli071f3f22018-05-24 16:45:30 +053093 setActFlag |= (setAccessMode | setUserAuthEnabled |
94 setMsgAuthEnabled | setAlertingEnabled);
95 break;
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000096
AppaRao Puli071f3f22018-05-24 16:45:30 +053097 case reserved:
98 default:
99 log<level::DEBUG>("Set channel access - Invalid access set mode");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000100 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530101 }
102
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000103 // cannot static cast directly from uint2_t to enum; must go via int
104 uint8_t channelPrivAction = static_cast<uint8_t>(channelPrivMode);
105 switch (static_cast<EChannelActionType>(channelPrivAction))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530106 {
107 case doNotSet:
AppaRao Puli071f3f22018-05-24 16:45:30 +0530108 break;
109 case nvData:
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000110 chNVData.privLimit = static_cast<uint8_t>(channelPrivLimit);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530111 setNVFlag |= setPrivLimit;
112 break;
113 case activeData:
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000114 chActData.privLimit = static_cast<uint8_t>(channelPrivLimit);
115
AppaRao Puli071f3f22018-05-24 16:45:30 +0530116 setActFlag |= setPrivLimit;
117 break;
118 case reserved:
119 default:
120 log<level::DEBUG>("Set channel access - Invalid access priv mode");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000121 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530122 }
123
124 if (setNVFlag != 0)
125 {
126 compCode = setChannelAccessPersistData(chNum, chNVData, setNVFlag);
127 if (compCode != IPMI_CC_OK)
128 {
129 log<level::DEBUG>("Set channel access - Failed to set access data");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000130 return response(compCode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530131 }
132 }
133
134 if (setActFlag != 0)
135 {
136 compCode = setChannelAccessData(chNum, chActData, setActFlag);
137 if (compCode != IPMI_CC_OK)
138 {
139 log<level::DEBUG>("Set channel access - Failed to set access data");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000140 return response(compCode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530141 }
142 }
143
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000144 return responseSuccess();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530145}
146
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530147/** @brief implements the get channel access command
148 * @ param ctx - context pointer
149 * @ param channel - channel number
150 * @ param reserved1 - skip 4 bits
151 * @ param reserved2 - skip 6 bits
152 * @ param accessMode - get access mode
153 *
154 * @returns ipmi completion code plus response data
155 * - accessMode - get access mode
156 * - usrAuthDisabled - user level authentication status
157 * - msgAuthDisabled - message level authentication status
158 * - alertDisabled - alerting status
159 * - reserved - skip 2 bits
160 * - privLimit - channel privilege limit
161 * - reserved - skip 4 bits
162 * */
163ipmi ::RspType<uint3_t, // access mode,
164 bool, // user authentication status,
165 bool, // message authentication status,
166 bool, // alerting status,
167 uint2_t, // reserved,
168
169 uint4_t, // channel privilege,
170 uint4_t // reserved
171 >
172 ipmiGetChannelAccess(Context::ptr ctx, uint4_t channel, uint4_t reserved1,
173 uint6_t reserved2, uint2_t accessSetMode)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530174{
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530175 const uint8_t chNum =
176 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530177
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530178 if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530179 {
Richard Marian Thomaiyaref024012019-01-29 11:06:39 +0530180 log<level::DEBUG>("Get channel access - Invalid field in request");
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530181 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530182 }
183
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530184 if ((accessSetMode == doNotSet) || (accessSetMode == reserved))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530185 {
186 log<level::DEBUG>("Get channel access - Invalid Access mode");
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530187 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530188 }
189
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530190 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530191 {
192 log<level::DEBUG>("Get channel access - No support on channel");
anil kumar appanaddb1f442019-07-04 18:07:27 +0000193 return response(ccActionNotSupportedForChannel);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530194 }
195
AppaRao Puli071f3f22018-05-24 16:45:30 +0530196 ChannelAccess chAccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530197
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530198 Cc compCode;
199
200 if (accessSetMode == nvData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530201 {
202 compCode = getChannelAccessPersistData(chNum, chAccess);
203 }
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530204 else if (accessSetMode == activeData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530205 {
206 compCode = getChannelAccessData(chNum, chAccess);
207 }
208
209 if (compCode != IPMI_CC_OK)
210 {
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530211 return response(compCode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530212 }
213
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530214 constexpr uint2_t reservedOut1 = 0;
215 constexpr uint4_t reservedOut2 = 0;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530216
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530217 return responseSuccess(
218 static_cast<uint3_t>(chAccess.accessMode), chAccess.userAuthDisabled,
219 chAccess.perMsgAuthDisabled, chAccess.alertingDisabled, reservedOut1,
220 static_cast<uint4_t>(chAccess.privLimit), reservedOut2);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530221}
222
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700223/** @brief implements the get channel info command
224 * @ param ctx - context pointer
225 * @ param channel - channel number
226 * @ param reserved - skip 4 bits
227 *
228 * @returns ipmi completion code plus response data
229 * - chNum - the channel number for this request
230 * - mediumType - see Table 6-3, Channel Medium Type Numbers
231 * - protocolType - Table 6-2, Channel Protocol Type Numbers
232 * - activeSessionCount - number of active sessions
233 * - sessionType - channel support for sessions
234 * - vendorId - vendor for this channel protocol (IPMI - 7154)
235 * - auxChInfo - auxiliary info for channel
236 * */
237RspType<uint4_t, // chNum
238 uint4_t, // reserved
239 uint7_t, // mediumType
240 bool, // reserved
241 uint5_t, // protocolType
242 uint3_t, // reserved
243 uint6_t, // activeSessionCount
244 uint2_t, // sessionType
245 uint24_t, // Vendor IANA
246 uint16_t // aux info
247 >
248 ipmiGetChannelInfo(Context::ptr ctx, uint4_t channel, uint4_t reserved)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530249{
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700250 uint8_t chNum =
251 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
252 if (!isValidChannel(chNum) || reserved)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530253 {
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700254 log<level::DEBUG>("Get channel access - Invalid field in request");
255 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530256 }
257
AppaRao Puli071f3f22018-05-24 16:45:30 +0530258 ChannelInfo chInfo;
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700259 Cc compCode = getChannelInfo(chNum, chInfo);
260 if (compCode != ccSuccess)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530261 {
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700262 log<level::ERR>("Failed to get channel info",
263 entry("CHANNEL=%x", chNum),
264 entry("ERRNO=%x", compCode));
265 return response(compCode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530266 }
267
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700268 constexpr uint4_t reserved1 = 0;
269 constexpr bool reserved2 = false;
270 constexpr uint3_t reserved3 = 0;
271 uint8_t mediumType = chInfo.mediumType;
272 uint8_t protocolType = chInfo.protocolType;
273 uint2_t sessionType = chInfo.sessionSupported;
274 uint6_t activeSessionCount = getChannelActiveSessions(chNum);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530275 // IPMI Spec: The IPMI Enterprise Number is: 7154 (decimal)
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700276 constexpr uint24_t vendorId = 7154;
277 constexpr uint16_t auxChInfo = 0;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530278
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700279 return responseSuccess(chNum, reserved1, mediumType, reserved2,
280 protocolType, reserved3, activeSessionCount,
281 sessionType, vendorId, auxChInfo);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530282}
283
Vernon Maueryf6092892019-05-02 16:35:10 -0700284namespace
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530285{
Vernon Maueryf6092892019-05-02 16:35:10 -0700286constexpr uint16_t standardPayloadBit(PayloadType p)
287{
288 return (1 << static_cast<size_t>(p));
289}
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530290
Vernon Maueryf6092892019-05-02 16:35:10 -0700291constexpr uint16_t sessionPayloadBit(PayloadType p)
292{
293 constexpr size_t sessionShift =
294 static_cast<size_t>(PayloadType::OPEN_SESSION_REQUEST);
295 return ((1 << static_cast<size_t>(p)) >> sessionShift);
296}
297} // namespace
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530298
Vernon Maueryf6092892019-05-02 16:35:10 -0700299/** @brief implements get channel payload support command
300 * @ param ctx - ipmi context pointer
301 * @ param chNum - channel number
302 * @ param reserved - skip 4 bits
303 *
304 * @ returns IPMI completion code plus response data
305 * - stdPayloadType - bitmask of supported standard payload types
306 * - sessSetupPayloadType - bitmask of supported session setup payload types
307 * - OEMPayloadType - bitmask of supported OEM payload types
308 * - reserved - 2 bytes of 0
309 **/
310RspType<uint16_t, // stdPayloadType
311 uint16_t, // sessSetupPayloadType
312 uint16_t, // OEMPayloadType
313 uint16_t // reserved
314 >
315 ipmiGetChannelPayloadSupport(Context::ptr ctx, uint4_t channel,
316 uint4_t reserved)
317{
318 uint8_t chNum =
319 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
320 if (!isValidChannel(chNum) || reserved)
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530321 {
Vernon Maueryf6092892019-05-02 16:35:10 -0700322 log<level::DEBUG>("Get channel access - Invalid field in request");
323 return responseInvalidFieldRequest();
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530324 }
325
326 // Session support is available in active LAN channels.
Vernon Maueryf6092892019-05-02 16:35:10 -0700327 if ((getChannelSessionSupport(chNum) == EChannelSessSupported::none) ||
328 !(doesDeviceExist(chNum)))
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530329 {
330 log<level::DEBUG>("Get channel payload - Device not exist");
Vernon Maueryf6092892019-05-02 16:35:10 -0700331 return responseInvalidFieldRequest();
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530332 }
333
Vernon Maueryf6092892019-05-02 16:35:10 -0700334 constexpr uint16_t stdPayloadType = standardPayloadBit(PayloadType::IPMI) |
335 standardPayloadBit(PayloadType::SOL);
336 constexpr uint16_t sessSetupPayloadType =
337 sessionPayloadBit(PayloadType::OPEN_SESSION_REQUEST) |
338 sessionPayloadBit(PayloadType::OPEN_SESSION_RESPONSE) |
339 sessionPayloadBit(PayloadType::RAKP1) |
340 sessionPayloadBit(PayloadType::RAKP2) |
341 sessionPayloadBit(PayloadType::RAKP3) |
342 sessionPayloadBit(PayloadType::RAKP4);
343 constexpr uint16_t OEMPayloadType = 0;
344 constexpr uint16_t rspRsvd = 0;
345 return responseSuccess(stdPayloadType, sessSetupPayloadType, OEMPayloadType,
346 rspRsvd);
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530347}
348
Ayushi Smriti6fd812d2019-04-12 18:51:31 +0000349/** @brief implements the get channel payload version command
350 * @param ctx - IPMI context pointer (for channel)
351 * @param chNum - channel number to get info about
352 * @param reserved - skip 4 bits
353 * @param payloadTypeNum - to get payload type info
354
355 * @returns IPMI completion code plus response data
356 * - formatVersion - BCD encoded format version info
357 */
358
359RspType<uint8_t> // formatVersion
360 ipmiGetChannelPayloadVersion(Context::ptr ctx, uint4_t chNum,
361 uint4_t reserved, uint8_t payloadTypeNum)
362{
363 uint8_t channel =
364 convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel);
365
366 if (reserved || !isValidChannel(channel) ||
367 (getChannelSessionSupport(channel)) == EChannelSessSupported::none)
368 {
369 return responseInvalidFieldRequest();
370 }
371
372 if (!isValidPayloadType(static_cast<PayloadType>(payloadTypeNum)))
373 {
374 log<level::ERR>("Channel payload version - Payload type unavailable");
375
376 constexpr uint8_t payloadTypeNotSupported = 0x80;
377 return response(payloadTypeNotSupported);
378 }
379
380 // BCD encoded version representation - 1.0
381 constexpr uint8_t formatVersion = 0x10;
382
383 return responseSuccess(formatVersion);
384}
385
William A. Kennington III343d0612018-12-10 15:56:24 -0800386void registerChannelFunctions() __attribute__((constructor));
AppaRao Puli071f3f22018-05-24 16:45:30 +0530387void registerChannelFunctions()
388{
389 ipmiChannelInit();
390
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000391 registerHandler(prioOpenBmcBase, netFnApp, app::cmdSetChannelAccess,
392 Privilege::Admin, ipmiSetChannelAccess);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530393
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530394 registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelAccess,
395 Privilege::User, ipmiGetChannelAccess);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530396
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700397 registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelInfoCommand,
398 Privilege::User, ipmiGetChannelInfo);
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530399
Vernon Maueryf6092892019-05-02 16:35:10 -0700400 registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadSupport,
401 Privilege::User, ipmiGetChannelPayloadSupport);
Ayushi Smriti6fd812d2019-04-12 18:51:31 +0000402
403 registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadVersion,
404 Privilege::User, ipmiGetChannelPayloadVersion);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530405}
406
407} // namespace ipmi