blob: 9d3b4d243b59346c4e7936aaf4f0758f0ef2224a [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
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000029/** @brief implements the set channel access command
30 * @ param ctx - context pointer
31 * @ param channel - channel number
32 * @ param reserved - skip 4 bits
33 * @ param accessMode - access mode for IPMI messaging
34 * @ param usrAuth - user level authentication (enable/disable)
35 * @ param msgAuth - per message authentication (enable/disable)
36 * @ param alertDisabled - PEF alerting (enable/disable)
37 * @ param chanAccess - channel access
38 * @ param channelPrivLimit - channel privilege limit
39 * @ param reserved - skip 3 bits
40 * @ param channelPrivMode - channel priviledge mode
41 *
42 * @ returns IPMI completion code
43 **/
44RspType<> ipmiSetChannelAccess(Context::ptr ctx, uint4_t channel,
45 uint4_t reserved1, uint3_t accessMode,
46 bool usrAuth, bool msgAuth, bool alertDisabled,
47 uint2_t chanAccess, uint4_t channelPrivLimit,
48 uint2_t reserved2, uint2_t channelPrivMode)
AppaRao Puli071f3f22018-05-24 16:45:30 +053049{
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000050 const uint8_t chNum =
51 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
AppaRao Puli071f3f22018-05-24 16:45:30 +053052
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000053 if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +053054 {
Richard Marian Thomaiyaref024012019-01-29 11:06:39 +053055 log<level::DEBUG>("Set channel access - Invalid field in request");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000056 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +053057 }
58
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000059 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
AppaRao Puli071f3f22018-05-24 16:45:30 +053060 {
61 log<level::DEBUG>("Set channel access - No support on channel");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000062 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +053063 }
64
65 ChannelAccess chActData;
66 ChannelAccess chNVData;
67 uint8_t setActFlag = 0;
68 uint8_t setNVFlag = 0;
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000069 Cc compCode;
AppaRao Puli071f3f22018-05-24 16:45:30 +053070
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000071 // cannot static cast directly from uint2_t to enum; must go via int
72 uint8_t channelAccessAction = static_cast<uint8_t>(chanAccess);
73 switch (static_cast<EChannelActionType>(channelAccessAction))
AppaRao Puli071f3f22018-05-24 16:45:30 +053074 {
75 case doNotSet:
AppaRao Puli071f3f22018-05-24 16:45:30 +053076 break;
77 case nvData:
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000078 chNVData.accessMode = static_cast<uint8_t>(accessMode);
79 chNVData.userAuthDisabled = usrAuth;
80 chNVData.perMsgAuthDisabled = msgAuth;
81 chNVData.alertingDisabled = alertDisabled;
AppaRao Puli071f3f22018-05-24 16:45:30 +053082 setNVFlag |= (setAccessMode | setUserAuthEnabled |
83 setMsgAuthEnabled | setAlertingEnabled);
84 break;
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000085
AppaRao Puli071f3f22018-05-24 16:45:30 +053086 case activeData:
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000087 chActData.accessMode = static_cast<uint8_t>(accessMode);
88 chActData.userAuthDisabled = usrAuth;
89 chActData.perMsgAuthDisabled = msgAuth;
90 chActData.alertingDisabled = alertDisabled;
AppaRao Puli071f3f22018-05-24 16:45:30 +053091 setActFlag |= (setAccessMode | setUserAuthEnabled |
92 setMsgAuthEnabled | setAlertingEnabled);
93 break;
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000094
AppaRao Puli071f3f22018-05-24 16:45:30 +053095 case reserved:
96 default:
97 log<level::DEBUG>("Set channel access - Invalid access set mode");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +000098 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +053099 }
100
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000101 // cannot static cast directly from uint2_t to enum; must go via int
102 uint8_t channelPrivAction = static_cast<uint8_t>(channelPrivMode);
103 switch (static_cast<EChannelActionType>(channelPrivAction))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530104 {
105 case doNotSet:
AppaRao Puli071f3f22018-05-24 16:45:30 +0530106 break;
107 case nvData:
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000108 chNVData.privLimit = static_cast<uint8_t>(channelPrivLimit);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530109 setNVFlag |= setPrivLimit;
110 break;
111 case activeData:
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000112 chActData.privLimit = static_cast<uint8_t>(channelPrivLimit);
113
AppaRao Puli071f3f22018-05-24 16:45:30 +0530114 setActFlag |= setPrivLimit;
115 break;
116 case reserved:
117 default:
118 log<level::DEBUG>("Set channel access - Invalid access priv mode");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000119 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530120 }
121
122 if (setNVFlag != 0)
123 {
124 compCode = setChannelAccessPersistData(chNum, chNVData, setNVFlag);
125 if (compCode != IPMI_CC_OK)
126 {
127 log<level::DEBUG>("Set channel access - Failed to set access data");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000128 return response(compCode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530129 }
130 }
131
132 if (setActFlag != 0)
133 {
134 compCode = setChannelAccessData(chNum, chActData, setActFlag);
135 if (compCode != IPMI_CC_OK)
136 {
137 log<level::DEBUG>("Set channel access - Failed to set access data");
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000138 return response(compCode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530139 }
140 }
141
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000142 return responseSuccess();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530143}
144
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530145/** @brief implements the get channel access command
146 * @ param ctx - context pointer
147 * @ param channel - channel number
148 * @ param reserved1 - skip 4 bits
149 * @ param reserved2 - skip 6 bits
150 * @ param accessMode - get access mode
151 *
152 * @returns ipmi completion code plus response data
153 * - accessMode - get access mode
154 * - usrAuthDisabled - user level authentication status
155 * - msgAuthDisabled - message level authentication status
156 * - alertDisabled - alerting status
157 * - reserved - skip 2 bits
158 * - privLimit - channel privilege limit
159 * - reserved - skip 4 bits
160 * */
161ipmi ::RspType<uint3_t, // access mode,
162 bool, // user authentication status,
163 bool, // message authentication status,
164 bool, // alerting status,
165 uint2_t, // reserved,
166
167 uint4_t, // channel privilege,
168 uint4_t // reserved
169 >
170 ipmiGetChannelAccess(Context::ptr ctx, uint4_t channel, uint4_t reserved1,
171 uint6_t reserved2, uint2_t accessSetMode)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530172{
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530173 const uint8_t chNum =
174 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530175
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530176 if (!isValidChannel(chNum) || reserved1 != 0 || reserved2 != 0)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530177 {
Richard Marian Thomaiyaref024012019-01-29 11:06:39 +0530178 log<level::DEBUG>("Get channel access - Invalid field in request");
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530179 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530180 }
181
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530182 if ((accessSetMode == doNotSet) || (accessSetMode == reserved))
AppaRao Puli071f3f22018-05-24 16:45:30 +0530183 {
184 log<level::DEBUG>("Get channel access - Invalid Access mode");
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530185 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530186 }
187
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530188 if (getChannelSessionSupport(chNum) == EChannelSessSupported::none)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530189 {
190 log<level::DEBUG>("Get channel access - No support on channel");
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530191 return response(IPMI_CC_ACTION_NOT_SUPPORTED_FOR_CHANNEL);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530192 }
193
AppaRao Puli071f3f22018-05-24 16:45:30 +0530194 ChannelAccess chAccess;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530195
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530196 Cc compCode;
197
198 if (accessSetMode == nvData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530199 {
200 compCode = getChannelAccessPersistData(chNum, chAccess);
201 }
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530202 else if (accessSetMode == activeData)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530203 {
204 compCode = getChannelAccessData(chNum, chAccess);
205 }
206
207 if (compCode != IPMI_CC_OK)
208 {
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530209 return response(compCode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530210 }
211
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530212 constexpr uint2_t reservedOut1 = 0;
213 constexpr uint4_t reservedOut2 = 0;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530214
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530215 return responseSuccess(
216 static_cast<uint3_t>(chAccess.accessMode), chAccess.userAuthDisabled,
217 chAccess.perMsgAuthDisabled, chAccess.alertingDisabled, reservedOut1,
218 static_cast<uint4_t>(chAccess.privLimit), reservedOut2);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530219}
220
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700221/** @brief implements the get channel info command
222 * @ param ctx - context pointer
223 * @ param channel - channel number
224 * @ param reserved - skip 4 bits
225 *
226 * @returns ipmi completion code plus response data
227 * - chNum - the channel number for this request
228 * - mediumType - see Table 6-3, Channel Medium Type Numbers
229 * - protocolType - Table 6-2, Channel Protocol Type Numbers
230 * - activeSessionCount - number of active sessions
231 * - sessionType - channel support for sessions
232 * - vendorId - vendor for this channel protocol (IPMI - 7154)
233 * - auxChInfo - auxiliary info for channel
234 * */
235RspType<uint4_t, // chNum
236 uint4_t, // reserved
237 uint7_t, // mediumType
238 bool, // reserved
239 uint5_t, // protocolType
240 uint3_t, // reserved
241 uint6_t, // activeSessionCount
242 uint2_t, // sessionType
243 uint24_t, // Vendor IANA
244 uint16_t // aux info
245 >
246 ipmiGetChannelInfo(Context::ptr ctx, uint4_t channel, uint4_t reserved)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530247{
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700248 uint8_t chNum =
249 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
250 if (!isValidChannel(chNum) || reserved)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530251 {
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700252 log<level::DEBUG>("Get channel access - Invalid field in request");
253 return responseInvalidFieldRequest();
AppaRao Puli071f3f22018-05-24 16:45:30 +0530254 }
255
AppaRao Puli071f3f22018-05-24 16:45:30 +0530256 ChannelInfo chInfo;
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700257 Cc compCode = getChannelInfo(chNum, chInfo);
258 if (compCode != ccSuccess)
AppaRao Puli071f3f22018-05-24 16:45:30 +0530259 {
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700260 log<level::ERR>("Failed to get channel info",
261 entry("CHANNEL=%x", chNum),
262 entry("ERRNO=%x", compCode));
263 return response(compCode);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530264 }
265
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700266 constexpr uint4_t reserved1 = 0;
267 constexpr bool reserved2 = false;
268 constexpr uint3_t reserved3 = 0;
269 uint8_t mediumType = chInfo.mediumType;
270 uint8_t protocolType = chInfo.protocolType;
271 uint2_t sessionType = chInfo.sessionSupported;
272 uint6_t activeSessionCount = getChannelActiveSessions(chNum);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530273 // IPMI Spec: The IPMI Enterprise Number is: 7154 (decimal)
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700274 constexpr uint24_t vendorId = 7154;
275 constexpr uint16_t auxChInfo = 0;
AppaRao Puli071f3f22018-05-24 16:45:30 +0530276
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700277 return responseSuccess(chNum, reserved1, mediumType, reserved2,
278 protocolType, reserved3, activeSessionCount,
279 sessionType, vendorId, auxChInfo);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530280}
281
Vernon Maueryf6092892019-05-02 16:35:10 -0700282namespace
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530283{
Vernon Maueryf6092892019-05-02 16:35:10 -0700284constexpr uint16_t standardPayloadBit(PayloadType p)
285{
286 return (1 << static_cast<size_t>(p));
287}
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530288
Vernon Maueryf6092892019-05-02 16:35:10 -0700289constexpr uint16_t sessionPayloadBit(PayloadType p)
290{
291 constexpr size_t sessionShift =
292 static_cast<size_t>(PayloadType::OPEN_SESSION_REQUEST);
293 return ((1 << static_cast<size_t>(p)) >> sessionShift);
294}
295} // namespace
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530296
Vernon Maueryf6092892019-05-02 16:35:10 -0700297/** @brief implements get channel payload support command
298 * @ param ctx - ipmi context pointer
299 * @ param chNum - channel number
300 * @ param reserved - skip 4 bits
301 *
302 * @ returns IPMI completion code plus response data
303 * - stdPayloadType - bitmask of supported standard payload types
304 * - sessSetupPayloadType - bitmask of supported session setup payload types
305 * - OEMPayloadType - bitmask of supported OEM payload types
306 * - reserved - 2 bytes of 0
307 **/
308RspType<uint16_t, // stdPayloadType
309 uint16_t, // sessSetupPayloadType
310 uint16_t, // OEMPayloadType
311 uint16_t // reserved
312 >
313 ipmiGetChannelPayloadSupport(Context::ptr ctx, uint4_t channel,
314 uint4_t reserved)
315{
316 uint8_t chNum =
317 convertCurrentChannelNum(static_cast<uint8_t>(channel), ctx->channel);
318 if (!isValidChannel(chNum) || reserved)
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530319 {
Vernon Maueryf6092892019-05-02 16:35:10 -0700320 log<level::DEBUG>("Get channel access - Invalid field in request");
321 return responseInvalidFieldRequest();
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530322 }
323
324 // Session support is available in active LAN channels.
Vernon Maueryf6092892019-05-02 16:35:10 -0700325 if ((getChannelSessionSupport(chNum) == EChannelSessSupported::none) ||
326 !(doesDeviceExist(chNum)))
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530327 {
328 log<level::DEBUG>("Get channel payload - Device not exist");
Vernon Maueryf6092892019-05-02 16:35:10 -0700329 return responseInvalidFieldRequest();
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530330 }
331
Vernon Maueryf6092892019-05-02 16:35:10 -0700332 constexpr uint16_t stdPayloadType = standardPayloadBit(PayloadType::IPMI) |
333 standardPayloadBit(PayloadType::SOL);
334 constexpr uint16_t sessSetupPayloadType =
335 sessionPayloadBit(PayloadType::OPEN_SESSION_REQUEST) |
336 sessionPayloadBit(PayloadType::OPEN_SESSION_RESPONSE) |
337 sessionPayloadBit(PayloadType::RAKP1) |
338 sessionPayloadBit(PayloadType::RAKP2) |
339 sessionPayloadBit(PayloadType::RAKP3) |
340 sessionPayloadBit(PayloadType::RAKP4);
341 constexpr uint16_t OEMPayloadType = 0;
342 constexpr uint16_t rspRsvd = 0;
343 return responseSuccess(stdPayloadType, sessSetupPayloadType, OEMPayloadType,
344 rspRsvd);
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530345}
346
Ayushi Smriti6fd812d2019-04-12 18:51:31 +0000347/** @brief implements the get channel payload version command
348 * @param ctx - IPMI context pointer (for channel)
349 * @param chNum - channel number to get info about
350 * @param reserved - skip 4 bits
351 * @param payloadTypeNum - to get payload type info
352
353 * @returns IPMI completion code plus response data
354 * - formatVersion - BCD encoded format version info
355 */
356
357RspType<uint8_t> // formatVersion
358 ipmiGetChannelPayloadVersion(Context::ptr ctx, uint4_t chNum,
359 uint4_t reserved, uint8_t payloadTypeNum)
360{
361 uint8_t channel =
362 convertCurrentChannelNum(static_cast<uint8_t>(chNum), ctx->channel);
363
364 if (reserved || !isValidChannel(channel) ||
365 (getChannelSessionSupport(channel)) == EChannelSessSupported::none)
366 {
367 return responseInvalidFieldRequest();
368 }
369
370 if (!isValidPayloadType(static_cast<PayloadType>(payloadTypeNum)))
371 {
372 log<level::ERR>("Channel payload version - Payload type unavailable");
373
374 constexpr uint8_t payloadTypeNotSupported = 0x80;
375 return response(payloadTypeNotSupported);
376 }
377
378 // BCD encoded version representation - 1.0
379 constexpr uint8_t formatVersion = 0x10;
380
381 return responseSuccess(formatVersion);
382}
383
William A. Kennington III343d0612018-12-10 15:56:24 -0800384void registerChannelFunctions() __attribute__((constructor));
AppaRao Puli071f3f22018-05-24 16:45:30 +0530385void registerChannelFunctions()
386{
387 ipmiChannelInit();
388
NITIN SHARMA89e4bf22019-05-02 13:03:58 +0000389 registerHandler(prioOpenBmcBase, netFnApp, app::cmdSetChannelAccess,
390 Privilege::Admin, ipmiSetChannelAccess);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530391
Richard Marian Thomaiyarbc5e9ba2019-05-07 13:32:48 +0530392 registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelAccess,
393 Privilege::User, ipmiGetChannelAccess);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530394
Vernon Mauery6f1e9782019-05-02 16:31:07 -0700395 registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelInfoCommand,
396 Privilege::User, ipmiGetChannelInfo);
Saravanan Palanisamyb5a0f162019-03-04 18:34:44 +0530397
Vernon Maueryf6092892019-05-02 16:35:10 -0700398 registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadSupport,
399 Privilege::User, ipmiGetChannelPayloadSupport);
Ayushi Smriti6fd812d2019-04-12 18:51:31 +0000400
401 registerHandler(prioOpenBmcBase, netFnApp, app::cmdGetChannelPayloadVersion,
402 Privilege::User, ipmiGetChannelPayloadVersion);
AppaRao Puli071f3f22018-05-24 16:45:30 +0530403}
404
405} // namespace ipmi