-
Notifications
You must be signed in to change notification settings - Fork 278
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
ELBERT: fscd: Add inital fscd scripts (#97)
Summary: ELBERT: fscd: Add inital fscd scripts - Add set_fan_speed, get_fan_speed script - Add placeholder fscd config profile. Currently this has dummy values and is not used - FSCD is not actually turned on yet as we waiting for thermal data - Fancpld typo fixed Testing: root@bmc-oob:~# get_fan_speed.sh Fan 1 RPMs: 7481, 7481, (30%) Fan 2 RPMs: 7462, 7462, (30%) Fan 3 RPMs: 7537, 7537, (30%) Fan 4 RPMs: 7444, 7444, (30%) Fan 5 RPMs: 7407, 7407, (30%) root@bmc-oob:~# set_fan_speed.sh 100 255 will be set to /sys/bus/i2c/drivers/fancpld/6-0060/fan1_pwm !!!! Successfully set fan 1 speed to 100% 255 will be set to /sys/bus/i2c/drivers/fancpld/6-0060/fan2_pwm !!!! Successfully set fan 2 speed to 100% 255 will be set to /sys/bus/i2c/drivers/fancpld/6-0060/fan3_pwm !!!! Successfully set fan 3 speed to 100% 255 will be set to /sys/bus/i2c/drivers/fancpld/6-0060/fan4_pwm !!!! Successfully set fan 4 speed to 100% 255 will be set to /sys/bus/i2c/drivers/fancpld/6-0060/fan5_pwm !!!! Successfully set fan 5 speed to 100% root@bmc-oob:~# get_fan_speed.sh Fan 1 RPMs: 14634, 14634, (100%) Fan 2 RPMs: 14563, 14563, (100%) Fan 3 RPMs: 14354, 14354, (100%) Fan 4 RPMs: 14354, 14354, (100%) Fan 5 RPMs: 14563, 14563, (100%) Pull Request resolved: facebookexternal/openbmc.arista#97 Reviewed By: benwei13 fbshipit-source-id: a32d5e083e
- Loading branch information
1 parent
5947c13
commit 5a77b78
Showing
8 changed files
with
470 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
132 changes: 132 additions & 0 deletions
132
meta-facebook/meta-elbert/recipes-utils/fscd/fscd/fsc-config.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
{ | ||
"pwm_transition_value": 50, | ||
"pwm_boost_value": 100, | ||
"sample_interval_ms": 3000, | ||
"boost": { | ||
"fan_fail": true, | ||
"sensor_fail": false, | ||
"progressive": true | ||
}, | ||
"fan_dead_boost": { | ||
"data": [ | ||
[1,100] | ||
] | ||
}, | ||
"watchdog": true, | ||
"min_rpm": 800, | ||
"profiles": { | ||
"linear_inlet": { | ||
"read_source" : { | ||
"sysfs" : "/sys/bus/i2c/drivers/lm90/11-004c/hwmon/hwmon*/temp2_input" | ||
}, | ||
"read_limit": { | ||
"valid": { | ||
"limit": 40, | ||
"threshold": 20, | ||
"action": "host_shutdown" | ||
}, | ||
"invalid": { | ||
"limit": -60, | ||
"threshold": 10, | ||
"action": "host_shutdown" | ||
} | ||
}, | ||
"type": "linear", | ||
"positive_hysteresis": 0, | ||
"negative_hysteresis": 1, | ||
"data": [ | ||
[25, 100], | ||
[30, 150], | ||
[35, 185], | ||
[36, 255] | ||
] | ||
}, | ||
"linear_th4": { | ||
"read_source" : { | ||
"sysfs" : "/sys/bus/i2c/drivers/max6697/4-004d/hwmon/hwmon*/temp2_input" | ||
}, | ||
"read_limit": { | ||
"valid": { | ||
"limit": 110, | ||
"threshold": 20, | ||
"action": "host_shutdown" | ||
}, | ||
"invalid": { | ||
"limit": -60, | ||
"threshold": 10, | ||
"action": "host_shutdown" | ||
} | ||
}, | ||
"type": "linear", | ||
"positive_hysteresis": 0, | ||
"negative_hysteresis": 1, | ||
"data": [ | ||
[15, 100], | ||
[110, 255] | ||
] | ||
} | ||
}, | ||
"fans": { | ||
"1": { | ||
"label" : "1", | ||
"read_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan1_input" | ||
}, | ||
"write_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan1_pwm", | ||
"max_duty_register": 255 | ||
} | ||
}, | ||
"2": { | ||
"label" : "2", | ||
"read_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan2_input" | ||
}, | ||
"write_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan2_pwm", | ||
"max_duty_register": 255 | ||
} | ||
}, | ||
"3": { | ||
"label" : "3", | ||
"read_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan3_input" | ||
}, | ||
"write_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan3_pwm", | ||
"max_duty_register": 255 | ||
} | ||
}, | ||
"4": { | ||
"label" : "4", | ||
"read_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan4_input" | ||
}, | ||
"write_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan4_pwm", | ||
"max_duty_register": 255 | ||
} | ||
}, | ||
"5": { | ||
"label" : "5", | ||
"read_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan5_input" | ||
}, | ||
"write_source" : { | ||
"sysfs": "/sys/bus/i2c/drivers/fancpld/6-0060/fan5_pwm", | ||
"max_duty_register": 255 | ||
} | ||
} | ||
}, | ||
"zones": { | ||
"zone_1": { | ||
"pwm_output": [1, 2, 3, 4, 5], | ||
"expr_file": "zone1.fsc" | ||
} | ||
}, | ||
"notes": { | ||
"fanx_pwm": { | ||
"0_to_255" : "the range that corresponds to 0_to_100 percent" | ||
} | ||
} | ||
} |
146 changes: 146 additions & 0 deletions
146
meta-facebook/meta-elbert/recipes-utils/fscd/fscd/fsc_board.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
# Copyright 2020-present Facebook. All Rights Reserved. | ||
# | ||
# This program file is free software; you can redistribute it and/or modify it | ||
# under the terms of the GNU General Public License as published by the | ||
# Free Software Foundation; version 2 of the License. | ||
# | ||
# This program is distributed in the hope that it will be useful, but WITHOUT | ||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
# for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program in a file named COPYING; if not, write to the | ||
# Free Software Foundation, Inc., | ||
# 51 Franklin Street, Fifth Floor, | ||
# Boston, MA 02110-1301 USA | ||
# | ||
import time | ||
from subprocess import PIPE, Popen | ||
|
||
from fsc_util import Logger | ||
|
||
|
||
# Overrides the functions that need to do HW dependent | ||
# actions, such as LED control, PWM full boost and | ||
# emergency shutdown | ||
|
||
|
||
def elbert_set_fan_led(fan, color="led_blue"): | ||
FCM_CPLD = "/sys/bus/i2c/drivers/fancpld/6-0060/" | ||
for fan in fan.split(): | ||
# ELBERT fans are all named as number | ||
if not fan.isdigit(): | ||
break | ||
fan = int(fan) | ||
if fan > 5 or fan < 1: | ||
break | ||
|
||
# 1 means off | ||
green_value = 1 | ||
red_value = 1 | ||
blue_value = 1 | ||
amber_value = 1 | ||
green_key = FCM_CPLD + "fan" + str(fan) + "_led_green" | ||
red_key = FCM_CPLD + "fan" + str(fan) + "_led_red" | ||
blue_key = FCM_CPLD + "fan" + str(fan) + "_led_blue" | ||
amber_key = FCM_CPLD + "fan" + str(fan) + "_led_amber" | ||
|
||
# 0 means on | ||
if "red" in color: | ||
red_value = 0 | ||
elif "blue" in color: | ||
blue_value = 0 | ||
elif "green" in color: | ||
green_value = 0 | ||
elif "amber" in color: | ||
amber_value = 0 | ||
else: | ||
return 0 # error | ||
|
||
cmd_green = "echo " + str(green_value) + " > " + green_key | ||
cmd_red = "echo " + str(red_value) + " > " + red_key | ||
cmd_blue = "echo " + str(blue_value) + " > " + blue_key | ||
cmd_amber = "echo " + str(amber_value) + " > " + amber_key | ||
|
||
# Do the best effort. When LED setting commands fail, move on, | ||
# as this failure alone will not damage or take down hardware | ||
Popen(cmd_green, shell=True, stdout=PIPE).stdout.read() | ||
Popen(cmd_red, shell=True, stdout=PIPE).stdout.read() | ||
Popen(cmd_blue, shell=True, stdout=PIPE).stdout.read() | ||
Popen(cmd_amber, shell=True, stdout=PIPE).stdout.read() | ||
return 0 | ||
|
||
|
||
def board_fan_actions(fan, action="None"): | ||
if "led" in action: | ||
elbert_set_fan_led(fan.label, color=action) | ||
else: | ||
Logger.warn("fscd: %s has no action %s" % (fan.label, str(action))) | ||
pass | ||
|
||
|
||
def elbert_set_all_pwm(boost): | ||
# The script name is same as Minipack. | ||
# Note that, the argument to this script is in range [0,100] | ||
# and the script will scale the value to [0,255] | ||
cmd = "/usr/local/bin/set_fan_speed.sh %d" % (boost) | ||
response = Popen(cmd, shell=True, stdout=PIPE).stdout.read() | ||
return response | ||
|
||
|
||
def board_callout(callout="None", **kwargs): | ||
if "init_fans" in callout: | ||
boost = 100 | ||
if "boost" in kwargs: | ||
boost = kwargs["boost"] | ||
Logger.info("FSC init fans to boost=%s " % str(boost)) | ||
return elbert_set_all_pwm(boost) | ||
else: | ||
Logger.warn("Need to perform callout action %s" % callout) | ||
pass | ||
|
||
|
||
# This function will run cmd_str and ignore any exception | ||
# We use this function for shutdown sequence, as the system may | ||
# be in a bad state where any command may fail | ||
def elbert_force_run_cmd(cmd_str): | ||
try: | ||
Popen(cmd_str, shell=True, stdout=PIPE).stdout.read() | ||
except Exception: | ||
pass | ||
return 0 | ||
|
||
|
||
def elbert_host_shutdown(): | ||
# Do the best effort by : | ||
# 1. Turn off CPU | ||
# 2. Then turn off SMB | ||
# 3. Then turn off all PSU | ||
# We do this because, if any one of CPLD/FPGA is already | ||
# malfunctioning, we still want to turn off as much part of | ||
# the system as possible. | ||
SMB_POWER_REG = "/sys/bus/i2c/drivers/smbcpld/4-0023/smb_power_en" | ||
CPU_OFF = "/usr/local/bin/wedge_power.sh off" | ||
SMB_OFF = "echo 0 > " + SMB_POWER_REG | ||
# First, turn off most of the switch board | ||
Logger.info("host_shutdown() executing {}".format(SMB_OFF)) | ||
elbert_force_run_cmd(SMB_OFF) | ||
time.sleep(3) | ||
# Then, turn off X86 CPU | ||
Logger.info("host_shutdown() executing {}".format(CPU_OFF)) | ||
elbert_force_run_cmd(CPU_OFF) | ||
|
||
# Until FSCD is proven to be very stable on most versions of FSCD, | ||
# we will only turn off SMB and BMC, but not PSUs. | ||
# (When PSUs are all turned off, it's hard to recover in DC) | ||
|
||
return 0 | ||
|
||
|
||
def board_host_actions(action="None", cause="None"): | ||
if "host_shutdown" in action: | ||
Logger.crit("Host is shutdown due to cause %s" % (str(cause),)) | ||
return elbert_host_shutdown() | ||
Logger.warn("Host needs action '%s' and cause '%s'" % (str(action), str(cause))) | ||
pass |
65 changes: 65 additions & 0 deletions
65
meta-facebook/meta-elbert/recipes-utils/fscd/fscd/get_fan_speed.sh
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
#!/bin/sh | ||
# | ||
# Copyright 2020-present Facebook. All Rights Reserved. | ||
# | ||
# This program file is free software; you can redistribute it and/or modify it | ||
# under the terms of the GNU General Public License as published by the | ||
# Free Software Foundation; version 2 of the License. | ||
# | ||
# This program is distributed in the hope that it will be useful, but WITHOUT | ||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
# for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with this program in a file named COPYING; if not, write to the | ||
# Free Software Foundation, Inc., | ||
# 51 Franklin Street, Fifth Floor, | ||
# Boston, MA 02110-1301 USA | ||
# | ||
|
||
|
||
usage() { | ||
echo "Usage: $0 [Fan Unit (1..5)]" >&2 | ||
} | ||
|
||
FCMCPLD="/sys/bus/i2c/drivers/fancpld/6-0060" | ||
|
||
show_pwm() | ||
{ | ||
pwm="$FCMCPLD/fan$1_pwm" | ||
val="$(head -n 1 "$pwm")" | ||
# Val is [0,255], so let's scale the value down to [0,100] | ||
float_val=$(echo "$val 100 * 255 / p" | dc) | ||
rounded="$(printf '%.*f' 0 "$float_val")" | ||
echo "$rounded%" | ||
} | ||
|
||
show_rpm() | ||
{ | ||
rpm="$(head -n 1 "$FCMCPLD"/fan"$1"_input)" | ||
# Keep the output in the same format as Minipack | ||
echo "$rpm, $rpm" | ||
} | ||
|
||
set -e | ||
|
||
# If user input is given, use it as FAN TRAY instance | ||
# Otherwise, read all | ||
if [ "$#" -eq 0 ]; then | ||
FANS="1 2 3 4 5" | ||
elif [ "$#" -eq 1 ]; then | ||
if [ "$1" -le 0 ] || [ "$1" -ge 6 ]; then | ||
echo "Fan $1: Should be between 1 and 5" | ||
exit 1 | ||
fi | ||
FANS="$1" | ||
else | ||
usage | ||
exit 1 | ||
fi | ||
|
||
|
||
for fan in $FANS; do | ||
echo "Fan $fan RPMs: $(show_rpm "$fan"), ($(show_pwm "$fan"))" | ||
done |
Oops, something went wrong.