Merge pull request #560 from jostar-yang/as9716_20190521

Add as9716-32d thermal plan
This commit is contained in:
Jeffrey Townsend
2019-06-12 10:46:55 -07:00
committed by GitHub

View File

@@ -37,22 +37,12 @@
#include "x86_64_accton_as9716_32d_int.h"
#include "x86_64_accton_as9716_32d_log.h"
#define NUM_OF_FAN_ON_MAIN_BROAD 6
#define PREFIX_PATH_ON_CPLD_DEV "/sys/bus/i2c/devices/"
#define NUM_OF_CPLD 3
#define FAN_DUTY_CYCLE_MAX (100)
#define FAN_DUTY_CYCLE_DEFAULT (32)
#define FAN_DUTY_PLUS_FOR_DIR (13)
/* Note, all chassis fans share 1 single duty setting.
* Here use fan 1 to represent global fan duty value.*/
#define FAN_ID_FOR_SET_FAN_DUTY (1)
#define CELSIUS_RECORD_NUMBER (2) /*Must >= 2*/
typedef struct fan_ctrl_policy {
int duty_cycle; /* In percetage */
int step_up_thermal; /* In mini-Celsius */
int step_dn_thermal; /* In mini-Celsius */
} fan_ctrl_policy_t;
#define FAN_DUTY_CYCLE_75 (75)
#define FAN_DUTY_CYCLE_50 (50)
static char arr_cplddev_name[NUM_OF_CPLD][10] =
{
@@ -99,7 +89,7 @@ onlp_sysi_oids_get(onlp_oid_t* table, int max)
onlp_oid_t* e = table;
memset(table, 0, max*sizeof(onlp_oid_t));
/* 6 Thermal sensors on the chassis */
/* 8 Thermal sensors on the chassis */
for (i = 1; i <= CHASSIS_THERMAL_COUNT; i++) {
*e++ = ONLP_THERMAL_ID_CREATE(i);
}
@@ -145,355 +135,397 @@ onlp_sysi_platform_info_free(onlp_platform_info_t* pi)
aim_free(pi->cpld_versions);
}
/* Thermal plan:
* $TMP = (CPU_core + LM75_1+ LM75_2 + LM75_3 + LM75_4)/5
* 1. If any FAN failed, set all the other fans as full speed, 100%.
* 2. If any sensor is high than 45 degrees, set fan speed to duty 62.5%.
* 3. If any sensor is high than 50 degrees, set fan speed to duty 100%.
* 4. When $TMP >= 40 C, set fan speed to duty 62.5%.
* 5. When $TMP >= 45 C, set fan speed to duty 100%.
* 6. When $TMP < 35 C, set fan speed to duty 31.25%.
* 7. Direction factor, when B2F, duty + 12.5%.
*
* Note, all chassis fans share 1 single duty setting.
/*Read fanN_direction=1: The air flow of Fan6 is <20><>AFI-Back to Front<6E><74>
* 0: The air flow of Fan6 is <20><>AFO-Front to back<63><6B>
*/
fan_ctrl_policy_t fan_ctrl_policy_avg[] = {
{FAN_DUTY_CYCLE_MAX , 45000, INT_MIN},
{63 , 40000, INT_MIN},
{32 , INT_MAX, 35000},
/*
Thermal policy:
One fan fail, set to fan pwm=100%
1. For AFI:
Default fan pwm will be 75%(LEVEL_FAN_DEF).
When below case, Fan pwm will be 100%(LEVEL_FAN_DAX)
(MB board)
LM75-1(0X48)<29><>61.5<EFBFBD>J
LM75-2(0X49)<29><>51.5<EFBFBD>J
LM75-3(0X4A)<29><>49.4<EFBFBD>J
LM75-4(0X4C)<29><>49.4<EFBFBD>J
LM75-5(0X4E)<29><>45.1<EFBFBD>J
LM75-6(0X4F)<29><>46.75<EFBFBD>J
(CPU board)
Core<72><65>48
LM75-1(0X4B)<29><>38.5<EFBFBD>J
When FAN pwm was 100%(LEVEL_FAN_MAX). If all below case meet with, set to 75%(LEVEL_FAN_DEF).
MB board
LM75-1(0X48)<29><>57<35>J
LM75-2(0X49)<29><>47.3<EFBFBD>J
LM75-3(0X4A)<29><>45<34>J
LM75-4(0X4C)<29><>45.1<EFBFBD>J
LM75-5(0X4E)<29><>40.75<EFBFBD>J
LM75-6(0X4F)<29><>42.1<EFBFBD>J
CPU board
Core<72><65>44
LM75-1(0X4B)<29><>35<33>J
2. For AFO:
Default fan pwm will be 50%(LEVEL_FAN_DEF).
When below case, Fan pwm will be 75%(LEVEL_FAN_MID)
(MB board)
LM75-1(0X48)<29><>67<36>J
LM75-2(0X49)<29><>62.5<EFBFBD>J
LM75-3(0X4A)<29><>65<36>J
LM75-4(0X4C)<29><>59<35>J
LM75-5(0X4E)<29><>58.5<EFBFBD>J
LM75-6(0X4F)<29><>63<36>J
(CPU board)
Core >=69<36>J
LM75-1(0X4B)<29><>49<34>J
When FAN pwm was 75%(LEVEL_FAN_MID). If all below case meet with, set to 100%(LEVEL_FAN_MAX).
(MB board)
LM75-1(0X48)<29><>70<37>J
LM75-2(0X49)<29><>66<36>J
LM75-3(0X4A)<29><>68<36>J
LM75-4(0X4C)<29><>62<36>J
LM75-5(0X4E)<29><>62<36>J
LM75-6(0X4F)<29><>67<36>J
(CPU board)
Core<72><65>77
LM75-1(0X4B)<29><>50<35>J
When FAN pwm was 100%(LEVEL_FAN_MAX). If all below case meet with, set to 75%(LEVEL_FAN_MID).
(MB board)
LM75-1(0X48)<29><>59<35>J
LM75-2(0X49)<29><>53.5<EFBFBD>J
LM75-3(0X4A)<29><>55.3<EFBFBD>J
LM75-4(0X4C)<29><>50.3<EFBFBD>J
LM75-5(0X4E)<29><>50<35>J
LM75-6(0X4F)<29><>52.5<EFBFBD>J
(CPU board)
Core<72><65>59
LM75-1(0X4B)<29><>41.1<EFBFBD>J
When FAN pwm was 75%(LEVEL_FAN_MID). If all below case meet with, set to 50%(LEVEL_FAN_DEF).
(MB board)
LM75-1(0X48)<29><>55.8<EFBFBD>J
LM75-2(0X49)<29><>50.5<EFBFBD>J
LM75-3(0X4A)<29><>51.1<EFBFBD>J
LM75-4(0X4C)<29><>47.6<EFBFBD>J
LM75-5(0X4E)<29><>45.75<EFBFBD>J
LM75-6(0X4F)<29><>50.1<EFBFBD>J
(CPU board)
Core<72><65>57
LM75-1(0X4B)<29><>36.6<EFBFBD>J
*/
typedef struct afi_temp_range{
int def_to_max_temp[8];
int max_to_def_temp[8];
}afi_temp_range_t;
afi_temp_range_t afi_thermal_spec={
{61500, 51500, 49400, 49400, 45100, 46750, 48000, 38500},
{57000, 47300, 45000, 45100, 40750, 42100, 44000, 35000}
};
fan_ctrl_policy_t fan_ctrl_policy_single[] = {
{FAN_DUTY_CYCLE_MAX , 50000, INT_MIN},
{63 , 45000, INT_MIN},
typedef struct afo_temp_range{
int def_to_mid_temp[8];
int mid_to_max_temp[8];
int max_to_mid_temp[8];
int mid_to_def_temp[8];
} afo_temp_range_t;
afo_temp_range_t afo_thermal_spec={
{67000, 62000, 65000, 59000, 58500, 63000, 69000, 49000},
{70000, 66000, 68000, 62000, 62000, 67000, 77000, 50000},
{59000, 53500, 55300, 50300, 50000, 52500, 59000, 41100},
{55800, 50500, 51100, 47600, 45750, 50100, 57000, 36600}
};
struct fan_control_data_s {
typedef struct fan_ctrl_policy {
int duty_cycle;
int dir_plus;
int mc_avg_pre[CELSIUS_RECORD_NUMBER];
int mc_high_pre[CELSIUS_RECORD_NUMBER];
int pwm;
int state;
} fan_ctrl_policy_t;
} fan_control_data_pre =
/*For AFI. 2 state. LEVEL_FAN_DEF(75%), LEVEL_FAN_MAX(100%)
For AFO. 3 state. LEVEL_FAN_DEF(50%), LEVEL_FAN_MID(75%), LEVEL_FAN_MAX(100%)
*/
enum
{
.duty_cycle = FAN_DUTY_CYCLE_DEFAULT,
.dir_plus = 0,
.mc_avg_pre = {INT_MIN+1, INT_MIN}, /*init as thermal rising to avoid full speed.*/
.mc_high_pre = {INT_MIN+1, INT_MIN}, /*init as thermal rising to avoid full speed.*/
LEVEL_FAN_INIT=0,
LEVEL_FAN_DEF=1,
LEVEL_FAN_MID,
LEVEL_FAN_MAX,
};
fan_ctrl_policy_t fan_thermal_policy_f2b[] = { /*AFO*/
{50, 0x7, LEVEL_FAN_DEF},
{75, 0xb, LEVEL_FAN_MID},
{100, 0xf, LEVEL_FAN_MAX},
};
static int
sysi_check_fan(uint32_t *fan_dir){
int i, present;
fan_ctrl_policy_t fan_thermal_policy_b2f[] = { /*AFI*/
{75, 0xb, LEVEL_FAN_DEF},
{100, 0xf, LEVEL_FAN_MAX}
};
for (i = 1; i <= CHASSIS_FAN_COUNT; i++)
int onlp_sysi_get_duty_cycle_by_fan_state(int state, int direction)
{
int i;
if(direction)
{
for(i=0; i< 2; i++)
{
if(state==fan_thermal_policy_b2f[i].state)
{
return fan_thermal_policy_b2f[i].duty_cycle;
}
}
}
else
{
for(i=0; i< 3; i++)
{
if(state==fan_thermal_policy_f2b[i].state)
{
return fan_thermal_policy_f2b[i].duty_cycle;
}
}
}
return 0;
}
#define FAN_SPEED_CTRL_PATH "/sys/bus/i2c/devices/17-0066/fan_duty_cycle_percentage"
#define FAN_DIRECTION_PATH "/sys/bus/i2c/devices/17-0066/fan1_direction"
static int fan_state=LEVEL_FAN_INIT;
static int fan_fail = 0;
int current_duty_cycle, new_duty_cycle;
int onlp_sysi_platform_manage_fans(void)
{
int i=0,k=0, ori_state=LEVEL_FAN_DEF, current_state=LEVEL_FAN_DEF;
int fd, len, direction_val=1;
int max_to_def=0, max_to_mid=0, mid_to_def=0; /* Only this flag equal to 8, otherwise state can not to be down.*/
onlp_thermal_info_t thermal[8];
char buf[10] = {0};
/* Get fan direction
*/
if (onlp_file_read_int(&direction_val, FAN_DIRECTION_PATH) < 0) {
AIM_LOG_ERROR("Unable to read status from file (%s)\r\n", FAN_DIRECTION_PATH);
}
/* Get current temperature
*/
for (i=2; i <5; i++)
{
if (onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(i), &thermal[k]) != ONLP_STATUS_OK )
{
AIM_LOG_ERROR("Unable to read thermal status, set fans to 75% speed");
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(i), 75);
return ONLP_STATUS_E_INTERNAL;
}
k++;
}
for (i=6; i <=8; i++)
{
if (onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(i), &thermal[k]) != ONLP_STATUS_OK )
{
AIM_LOG_ERROR("Unable to read thermal status, set fans to 75% speed");
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(i), 75);
return ONLP_STATUS_E_INTERNAL;
}
k++;
}
if (onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(1), &thermal[6]) != ONLP_STATUS_OK )
{
AIM_LOG_ERROR("Unable to read thermal status, set fans to 75% speed");
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), 75);
return ONLP_STATUS_E_INTERNAL;
}
if (onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(5), &thermal[7]) != ONLP_STATUS_OK )
{
AIM_LOG_ERROR("Unable to read thermal status, set fans to 75% speed");
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(5), 75);
return ONLP_STATUS_E_INTERNAL;
}
/* Get current fan pwm percent
*/
fd = open(FAN_SPEED_CTRL_PATH, O_RDONLY);
if (fd == -1){
AIM_LOG_ERROR("Unable to open fan speed control node (%s)", FAN_SPEED_CTRL_PATH);
return ONLP_STATUS_E_INTERNAL;
}
len = read(fd, buf, sizeof(buf));
close(fd);
if (len <= 0) {
AIM_LOG_ERROR("Unable to read fan speed from (%s)", FAN_SPEED_CTRL_PATH);
return ONLP_STATUS_E_INTERNAL;
}
current_duty_cycle = atoi(buf);
current_state=ori_state=fan_state;
/* Check thermal is in which range. */
max_to_def=0;
if(direction_val==1) /* AFI */
{
if(fan_state==LEVEL_FAN_INIT)
{
current_state=LEVEL_FAN_DEF;
}
for (i=0; i <CHASSIS_THERMAL_COUNT; i++)
{
if (thermal[i].mcelsius >= afi_thermal_spec.def_to_max_temp[i])
{
current_state=LEVEL_FAN_MAX;
break;
}
if (thermal[i].mcelsius <= afi_thermal_spec.def_to_max_temp[i])
{
max_to_def++;
}
}
if(max_to_def==CHASSIS_THERMAL_COUNT && fan_state==LEVEL_FAN_MAX)
{
current_state=LEVEL_FAN_DEF;
}
}
else /* AFO */
{
if(fan_state==LEVEL_FAN_INIT)
{
current_state=LEVEL_FAN_DEF;
}
for (i=0; i <CHASSIS_THERMAL_COUNT; i++)
{
if (thermal[i].mcelsius >= afo_thermal_spec.def_to_mid_temp[i])
{
current_state=LEVEL_FAN_MID;
}
if (thermal[i].mcelsius >= afo_thermal_spec.mid_to_max_temp[i])
{
current_state=LEVEL_FAN_MAX;
break;
}
if (thermal[i].mcelsius <= afo_thermal_spec.max_to_mid_temp[i])
{
max_to_mid++;
}
if (thermal[i].mcelsius <= afo_thermal_spec.mid_to_def_temp[i])
{
mid_to_def++;
}
}
if(max_to_mid==CHASSIS_THERMAL_COUNT && fan_state==LEVEL_FAN_MAX)
{
current_state=LEVEL_FAN_MID;
}
if(mid_to_def==CHASSIS_THERMAL_COUNT && fan_state==LEVEL_FAN_MID)
{
current_state=LEVEL_FAN_DEF;
}
}
// fan_state = current_state;
/*
for(i=0; i < sizeof(fan_thermal_policy_f2b)/sizeof(fan_ctrl_policy_t); i++)
{
if (temp > fan_thermal_policy[i].temp_down)
{
if (temp <= fan_thermal_policy[i].temp_up)
{
current_state =i;
}
}
}
*/
/* Get each fan status
*/
for (i = 1; i <= NUM_OF_FAN_ON_MAIN_BROAD; i++)
{
onlp_fan_info_t fan_info;
if (onlp_fani_info_get(ONLP_FAN_ID_CREATE(i), &fan_info) != ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to get fan(%d) status\r\n", i);
return ONLP_STATUS_E_INTERNAL;
}
present = fan_info.status & ONLP_FAN_STATUS_PRESENT;
if ((fan_info.status & ONLP_FAN_STATUS_FAILED) || !present) {
AIM_LOG_WARN("Fan(%d) is not working, set the other fans as full speed\r\n", i);
int ret = onlp_fani_percentage_set(
ONLP_FAN_ID_CREATE(FAN_ID_FOR_SET_FAN_DUTY), FAN_DUTY_CYCLE_MAX);
if (ret != ONLP_STATUS_OK)
return ret;
else
return ONLP_STATUS_E_MISSING;
}
/* Get fan direction (Only get the first one since all fan direction are the same)
AIM_LOG_ERROR("Unable to get fan(%d) status, try to set the other fans as full speed\r\n", i);
if(current_duty_cycle != FAN_DUTY_CYCLE_MAX)
{
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MAX);
}
fan_fail=1;
break;
}
/* Decision 1: Set fan as full speed if any fan is failed.
*/
if (i == 1) {
*fan_dir = fan_info.status & (ONLP_FAN_STATUS_F2B|ONLP_FAN_STATUS_B2F);
}
}
return ONLP_STATUS_OK;
}
static int
sysi_get_fan_duty(int *cur_duty_cycle){
int fd, len;
char buf[10] = {0};
char *node = FAN_NODE(fan_duty_cycle_percentage);
/* Get current fan duty*/
fd = open(node, O_RDONLY);
if (fd == -1){
AIM_LOG_ERROR("Unable to open fan speed control node (%s)", node);
return ONLP_STATUS_E_INTERNAL;
}
len = read(fd, buf, sizeof(buf));
close(fd);
if (len <= 0) {
AIM_LOG_ERROR("Unable to read fan speed from (%s)", node);
return ONLP_STATUS_E_INTERNAL;
}
*cur_duty_cycle = atoi(buf);
return ONLP_STATUS_OK;
}
static int
sysi_get_thermal_sum(int *mcelsius){
onlp_thermal_info_t thermal_info;
int i;
*mcelsius = 0;
for (i = 1; i <= CHASSIS_THERMAL_COUNT; i++) {
if (onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(i), &thermal_info)
!= ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to read thermal status");
return ONLP_STATUS_E_INTERNAL;
if (fan_info.status & ONLP_FAN_STATUS_FAILED || !(fan_info.status & ONLP_FAN_STATUS_PRESENT)) {
AIM_LOG_ERROR("Fan(%d) is not working, set the other fans as full speed\r\n", i);
if(current_duty_cycle != FAN_DUTY_CYCLE_MAX)
{
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MAX);
}
*mcelsius += thermal_info.mcelsius;
DEBUG_PRINT("Thermal %d: %d \n ", i, thermal_info.mcelsius);
}
return ONLP_STATUS_OK;
}
static int
sysi_get_highest_thermal(int *mcelsius){
onlp_thermal_info_t thermal_info;
int i, highest;
highest = 0;
for (i = 1; i <= CHASSIS_THERMAL_COUNT; i++) {
if (onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(i), &thermal_info)
!= ONLP_STATUS_OK) {
AIM_LOG_ERROR("Unable to read thermal status");
return ONLP_STATUS_E_INTERNAL;
}
highest = (thermal_info.mcelsius > highest)?
thermal_info.mcelsius : highest;
}
*mcelsius = highest;
return ONLP_STATUS_OK;
}
/* Anaylze thermal changing history to judge if the change is a stable trend. */
static int _is_thermal_a_trend(int *mc_history){
int i, trend, trended;
if (mc_history == NULL) {
AIM_LOG_ERROR("Unable to get history of thermal\n");
return 0;
}
/* Get heat up/down trend. */
trend = 0;
for (i = 0; i < CELSIUS_RECORD_NUMBER; i++) {
if (( mc_history[i+1] < mc_history[i])){
trend++;
}else if (( mc_history[i+1] > mc_history[i])){
trend--;
}
}
trended = (abs(trend) >= ((CELSIUS_RECORD_NUMBER+1)/2))? 1:0;
#if (DEBUG_MODE == 1)
DEBUG_PRINT("[INFO]%s#%d, trended: %d, UP/DW: %d mcelsius:",
__func__, __LINE__, trended, trend );
for (i = 0; i <= CELSIUS_RECORD_NUMBER; i++) {
DEBUG_PRINT(" %d =>", mc_history[i]);
}
DEBUG_PRINT("%c\n", ' ');
#endif
/*For more than half changes are same direction, it's a firm trend.*/
return trended;
}
/* Decide duty by highest value of thermal sensors.*/
static int
sysi_get_duty_by_highest(int *duty_cycle){
int i, ret, maxtrix_len;
int new_duty_cycle = 0 ;
int mc_history[CELSIUS_RECORD_NUMBER+1] = {0};
int *mcelsius_pre_p = &mc_history[1];
int *mcelsius_now_p = &mc_history[0];
/* Fill up mcelsius array,
* [0] is current temperature, others are history.
*/
ret = sysi_get_highest_thermal(mcelsius_now_p);
if(ONLP_STATUS_OK != ret){
return ret;
}
memcpy (mcelsius_pre_p, fan_control_data_pre.mc_high_pre,
sizeof(fan_control_data_pre.mc_high_pre));
DEBUG_PRINT("[INFO]%s#%d, highest mcelsius:%d!\n",
__func__, __LINE__, *mcelsius_now_p);
/* Shift records to the right */
for (i = 0; i < CELSIUS_RECORD_NUMBER; i++) {
fan_control_data_pre.mc_high_pre[i] = mc_history[i];
}
/* Only change duty on consecutive heat rising or falling.*/
maxtrix_len = AIM_ARRAYSIZE(fan_ctrl_policy_single);
/* Only change duty when the thermal changing are firm. */
if (_is_thermal_a_trend(mc_history))
{
int matched = 0;
for (i = 0; i < maxtrix_len; i++) {
if ((*mcelsius_now_p > fan_ctrl_policy_single[i].step_up_thermal)) {
new_duty_cycle = fan_ctrl_policy_single[i].duty_cycle;
matched = !matched;
break;
}
}
/* if (!matched) {
DEBUG_PRINT("%s#%d, celsius(%d) falls into undefined range!!\n",
__func__, __LINE__, *mcelsius_now_p);
} */
}
*duty_cycle = new_duty_cycle;
return ONLP_STATUS_OK;
}
/* Decide duty by average value of thermal sensors.*/
static int
sysi_get_duty_by_average(int *duty_cycle){
int i, mcelsius_avg, ret, maxtrix_len;
int new_duty_cycle=0;
int mc_history[CELSIUS_RECORD_NUMBER+1] = {0};
int *mcelsius_pre_p = &mc_history[1];
int *mcelsius_now_p = &mc_history[0];
/* Fill up mcelsius array,
* [0] is current temperature, others are history.
*/
*mcelsius_now_p = 0;
ret = sysi_get_thermal_sum(mcelsius_now_p);
if(ONLP_STATUS_OK != ret){
return ret;
}
mcelsius_avg = (*mcelsius_now_p)/CHASSIS_THERMAL_COUNT;
memcpy (mcelsius_pre_p, fan_control_data_pre.mc_avg_pre,
sizeof(fan_control_data_pre.mc_avg_pre));
DEBUG_PRINT("[INFO]%s#%d, mcelsius:%d!\n", __func__, __LINE__, mcelsius_avg);
/* Shift records to the right */
for (i = 0; i < CELSIUS_RECORD_NUMBER; i++) {
fan_control_data_pre.mc_avg_pre[i] = mc_history[i];
}
/* Only change duty on consecutive heat rising or falling.*/
maxtrix_len = AIM_ARRAYSIZE(fan_ctrl_policy_avg);
/* Only change duty when the thermal changing are firm. */
if (_is_thermal_a_trend(mc_history))
{
int matched = 0;
for (i = 0; i < maxtrix_len; i++) {
if ((mcelsius_avg >= fan_ctrl_policy_avg[i].step_up_thermal)) {
new_duty_cycle = fan_ctrl_policy_avg[i].duty_cycle;
matched = !matched;
break;
}
}
for (i = maxtrix_len-1; i>=0; i--) {
if ((mcelsius_avg < fan_ctrl_policy_avg[i].step_dn_thermal)) {
new_duty_cycle = fan_ctrl_policy_avg[i].duty_cycle;
matched = !matched;
fan_fail=1;
break;
}
}
/*if (!matched) {
DEBUG_PRINT("%s#%d, celsius(%d) falls into undefined range!!\n",
__func__, __LINE__, mcelsius_avg);
} */
}
*duty_cycle = new_duty_cycle;
return ONLP_STATUS_OK;
}
int
onlp_sysi_platform_manage_fans(void)
{
uint32_t fan_dir;
int ret;
int cur_duty_cycle, new_duty_cycle, tmp;
int direct_addon = 0;
onlp_oid_t fan_duty_oid = ONLP_FAN_ID_CREATE(FAN_ID_FOR_SET_FAN_DUTY);
/**********************************************************
* Decision 1: Set fan as full speed if any fan is failed.
**********************************************************/
ret = sysi_check_fan(&fan_dir);
if(ONLP_STATUS_OK != ret){
return ret;
}
if (fan_dir & ONLP_FAN_STATUS_B2F) {
direct_addon = FAN_DUTY_PLUS_FOR_DIR;
}
/**********************************************************
* Decision 2: If no matched fan speed is found from the policy,
* use FAN_DUTY_CYCLE_MIN as default speed
**********************************************************/
ret = sysi_get_fan_duty(&cur_duty_cycle);
if(ONLP_STATUS_OK != ret){
return ret;
}
/**********************************************************
* Decision 3: Decide new fan speed depend on fan direction and temperature
**********************************************************/
ret = sysi_get_duty_by_average(&new_duty_cycle);
if (ONLP_STATUS_OK != ret){
return ret;
}
ret = sysi_get_duty_by_highest(&tmp);
if (ONLP_STATUS_OK != ret){
return ret;
}
new_duty_cycle = (tmp > new_duty_cycle)? tmp : new_duty_cycle;
if (new_duty_cycle == 0)
if(current_state!=ori_state)
{
new_duty_cycle = fan_control_data_pre.duty_cycle;
} else {
fan_control_data_pre.duty_cycle = new_duty_cycle;
}
fan_control_data_pre.dir_plus = direct_addon;
DEBUG_PRINT("[INFO]%s#%d, new duty: %d = %d + %d (%d)!\n", __func__, __LINE__,
new_duty_cycle + direct_addon, new_duty_cycle, direct_addon, cur_duty_cycle);
new_duty_cycle += direct_addon;
new_duty_cycle = (new_duty_cycle > FAN_DUTY_CYCLE_MAX)?
FAN_DUTY_CYCLE_MAX : new_duty_cycle;
if (new_duty_cycle == cur_duty_cycle) {
/* Duty cycle does not change, just return */
return ONLP_STATUS_OK;
}
fan_state=current_state;
new_duty_cycle=onlp_sysi_get_duty_cycle_by_fan_state(current_state, direction_val);
if(new_duty_cycle!=current_duty_cycle && !fan_fail)
{
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), new_duty_cycle);
}
if(!new_duty_cycle && !fan_fail)
{
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MAX);
}
switch (ori_state)
{
case LEVEL_FAN_INIT:
break;
case LEVEL_FAN_DEF:
break;
case LEVEL_FAN_MID:
break;
case LEVEL_FAN_MAX:
break;
default:
AIM_SYSLOG_WARN("onlp_sysi_platform_manage_fans abnormal state", "onlp_sysi_platform_manage_fans abnormal state", "onlp_sysi_platform_manage_fans at abnormal state\n");
break;
}
}
return 0;
}
return onlp_fani_percentage_set(fan_duty_oid, new_duty_cycle);
}
int
onlp_sysi_platform_manage_leds(void)
{
return ONLP_STATUS_E_UNSUPPORTED;
}