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 /** @enum MtmLvl 60 .* 61 * Manufacturing command access levels 62 */ 63 enum class MtmLvl 64 { 65 mtmNotRunning = 0x00, 66 mtmExpired = 0x01, 67 mtmAvailable = 0x02, 68 }; 69 70 enum class SmActionGet : uint8_t 71 { 72 sample = 0, 73 ignore = 1, 74 revert = 2 75 }; 76 77 enum class SmActionSet : uint8_t 78 { 79 forceDeasserted = 0, 80 forceAsserted = 1, 81 revert = 2 82 }; 83 84 enum class SmSignalGet : uint8_t 85 { 86 smPowerButton = 0, 87 smResetButton = 1, 88 smSleepButton, 89 smNMIButton = 3, 90 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, 103 smGetSignalMax 104 }; 105 106 enum 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 128 struct SetSmSignalReq 129 { 130 SmSignalSet Signal; 131 uint8_t Instance; 132 SmActionSet Action; 133 uint8_t Value; 134 }; 135 136 class 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 */ 191 class 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 230 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); 236 int8_t disablePidControlService(const bool disable); 237 238 void revertTimerHandler(); 239 240 MtmLvl getAccessLvl(void) 241 { 242 static MtmLvl mtmMode = MtmLvl::mtmNotRunning; 243 if (mtmMode != MtmLvl::mtmExpired) 244 { 245 ipmi::Value mode; 246 if (getProperty("xyz.openbmc_project.SpecialMode", 247 "/xyz/openbmc_project/security/special_mode", 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 259 bool revertFanPWM = false; 260 bool revertLedCallback = false; 261 phosphor::Timer revertTimer; 262 }; 263 264 } // namespace ipmi 265