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