blob: a6ac45f9b854abab18ce37d923e6b1266d405e7f [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
17#pragma once
18
19#include <ipmid/api-types.hpp>
20#include <ipmid/utils.hpp>
21#include <phosphor-logging/log.hpp>
22#include <sdbusplus/bus.hpp>
23#include <sdbusplus/message.hpp>
24#include <sdbusplus/timer.hpp>
25#include <variantvisitors.hpp>
26#include <vector>
27
28#define FAN_SENSOR_NOT_PRESENT (0 << 0)
29#define FAN_SENSOR_PRESENT (1 << 0)
30#define FAN_NOT_PRESENT (0 << 1)
31#define FAN_PRESENT (1 << 1)
32
33namespace ipmi
34{
35
36// TODO: Service names may change. Worth to consider dynamic detection.
37static constexpr const char* fanService = "xyz.openbmc_project.FanSensor";
Jason M. Bills38d2b5a2019-06-03 16:26:11 -070038static constexpr const char* buttonService =
39 "xyz.openbmc_project.Chassis.Buttons";
Vernon Mauerya3702c12019-05-22 13:20:59 -070040static constexpr const char* ledServicePrefix =
41 "xyz.openbmc_project.LED.Controller.";
42
43static constexpr const char* ledPathPrefix =
44 "/xyz/openbmc_project/led/physical/";
45static constexpr const char* fanPwmPath =
46 "/xyz/openbmc_project/sensors/fan_pwm/Pwm_";
47static constexpr const char* fanTachPathPrefix =
48 "/xyz/openbmc_project/sensors/fan_tach/Fan_";
49
50static constexpr const char* fanIntf = "xyz.openbmc_project.Sensor.Value";
Jason M. Bills38d2b5a2019-06-03 16:26:11 -070051static constexpr const char* buttonIntf = "xyz.openbmc_project.Chassis.Buttons";
Vernon Mauerya3702c12019-05-22 13:20:59 -070052static constexpr const char* ledIntf = "xyz.openbmc_project.Led.Physical";
53
54static constexpr const char* busPropertyIntf =
55 "org.freedesktop.DBus.Properties";
56static constexpr const char* ledStateStr =
57 "xyz.openbmc_project.Led.Physical.Action."; // Comes with postfix Off/On
Vernon Mauerya3702c12019-05-22 13:20:59 -070058
59/** @enum MtmLvl
60.*
61 * Manufacturing command access levels
62 */
63enum class MtmLvl
64{
65 mtmNotRunning = 0x00,
66 mtmExpired = 0x01,
67 mtmAvailable = 0x02,
68};
69
70enum class SmActionGet : uint8_t
71{
72 sample = 0,
73 ignore = 1,
74 revert = 2
75};
76
77enum class SmActionSet : uint8_t
78{
79 forceDeasserted = 0,
80 forceAsserted = 1,
81 revert = 2
82};
83
84enum class SmSignalGet : uint8_t
85{
86 smPowerButton = 0,
87 smResetButton = 1,
88 smSleepButton,
Jason M. Bills38d2b5a2019-06-03 16:26:11 -070089 smNMIButton = 3,
Vernon Mauerya3702c12019-05-22 13:20:59 -070090 smChassisIntrusion = 4,
91 smPowerGood,
92 smPowerRequestGet,
93 smSleepRequestGet,
94 smFrbTimerHaltGet,
95 smForceUpdate,
96 smRingIndication,
97 smCarrierDetect,
98 smIdentifyButton = 0xc,
99 smFanPwmGet = 0xd,
100 smSignalReserved,
101 smFanTachometerGet = 0xf,
102 smNcsiDiag = 0x10,
Vernon Mauerya3702c12019-05-22 13:20:59 -0700103 smGetSignalMax
104};
105
106enum class SmSignalSet : uint8_t
107{
108 smPowerLed = 0,
109 smPowerFaultLed,
110 smClusterLed,
111 smDiskFaultLed,
112 smCoolingFaultLed,
113 smFanPowerSpeed = 5,
114 smPowerRequestSet,
115 smSleepRequestSet,
116 smAcpiSci,
117 smSpeaker,
118 smFanPackFaultLed,
119 smCpuFailLed,
120 smDimmFailLed,
121 smIdentifyLed,
122 smHddLed,
123 smSystemReadyLed,
124 smLcdBacklight = 0x10,
125 smSetSignalMax
126};
127
128struct SetSmSignalReq
129{
130 SmSignalSet Signal;
131 uint8_t Instance;
132 SmActionSet Action;
133 uint8_t Value;
134};
135
Vernon Mauerya3702c12019-05-22 13:20:59 -0700136class LedProperty
137{
138 SmSignalSet signal;
139 std::string name;
140 std::string prevState;
141 std::string currentState;
142 bool isLocked;
143
144 public:
145 LedProperty(SmSignalSet signal_, std::string name_) :
146 signal(signal_), name(name_), prevState(""), isLocked(false)
147 {
148 }
149
150 LedProperty() = delete;
151
152 SmSignalSet getSignal() const
153 {
154 return signal;
155 }
156
157 void setLock(const bool& lock)
158 {
159 isLocked = lock;
160 }
161 void setPrevState(const std::string& state)
162 {
163 prevState = state;
164 }
165 void setCurrState(const std::string& state)
166 {
167 currentState = state;
168 }
169 std::string getCurrState() const
170 {
171 return currentState;
172 }
173 bool getLock() const
174 {
175 return isLocked;
176 }
177 std::string getPrevState() const
178 {
179 return prevState;
180 }
181 std::string getName() const
182 {
183 return name;
184 }
185};
186
187/** @class Manufacturing
188 *
189 * @brief Implemet commands to support Manufacturing Test Mode.
190 */
191class Manufacturing
192{
193 std::string path;
194 std::string gpioPaths[(uint8_t)SmSignalGet::smGetSignalMax];
195 std::vector<LedProperty> ledPropertyList;
196 void initData();
197
198 public:
199 Manufacturing();
200
201 ipmi_return_codes detectAccessLvl(ipmi_request_t request,
202 ipmi_data_len_t req_len);
203
204 LedProperty* findLedProperty(const SmSignalSet& signal)
205 {
206 auto it = std::find_if(ledPropertyList.begin(), ledPropertyList.end(),
207 [&signal](const LedProperty& led) {
208 return led.getSignal() == signal;
209 });
210 if (it != ledPropertyList.end())
211 {
212 return &(*it);
213 }
214 return nullptr;
215 }
216
217 std::string getLedPropertyName(const SmSignalSet signal)
218 {
219 LedProperty* led = findLedProperty(signal);
220 if (led != nullptr)
221 {
222 return led->getName();
223 }
224 else
225 {
226 return "";
227 }
228 }
229
Jason M. Bills38d2b5a2019-06-03 16:26:11 -0700230 int8_t getProperty(const std::string& service, const std::string& path,
231 const std::string& interface,
232 const std::string& propertyName, ipmi::Value* value);
233 int8_t setProperty(const std::string& service, const std::string& path,
234 const std::string& interface,
235 const std::string& propertyName, ipmi::Value value);
Vernon Mauerya3702c12019-05-22 13:20:59 -0700236 int8_t disablePidControlService(const bool disable);
237
238 void revertTimerHandler();
239
Vernon Mauerya3702c12019-05-22 13:20:59 -0700240 MtmLvl getAccessLvl(void)
241 {
242 static MtmLvl mtmMode = MtmLvl::mtmNotRunning;
243 if (mtmMode != MtmLvl::mtmExpired)
244 {
245 ipmi::Value mode;
Jason M. Bills38d2b5a2019-06-03 16:26:11 -0700246 if (getProperty("xyz.openbmc_project.SpecialMode",
Vernon Mauerya3702c12019-05-22 13:20:59 -0700247 "/xyz/openbmc_project/security/specialMode",
248 "xyz.openbmc_project.Security.SpecialMode",
249 "SpecialMode", &mode) != 0)
250 {
251 mtmMode = MtmLvl::mtmExpired;
252 return mtmMode;
253 }
254 mtmMode = static_cast<MtmLvl>(std::get<std::uint8_t>(mode));
255 }
256 return mtmMode;
257 }
258
Vernon Mauerya3702c12019-05-22 13:20:59 -0700259 bool revertFanPWM = false;
260 bool revertLedCallback = false;
261 phosphor::Timer revertTimer;
262};
263
264} // namespace ipmi