static int onlp_fan_info_get_locked__(onlp_oid_t oid, onlp_fan_info_t* fip) { int rv; VALIDATE(oid); /* Get the information struct from the platform */ rv = onlp_fani_info_get(oid, fip); if(rv >= 0) { #if ONLP_CONFIG_INCLUDE_PLATFORM_OVERRIDES == 1 /* * Optional override from the config file. * This is usually just for testing. */ int id = ONLP_OID_ID_GET(oid); cJSON* entry = NULL; cjson_util_lookup(onlp_json_get(0), &entry, "overrides.fan.%d", id); onlp_fani_info_from_json__(entry, fip, 0); #endif if(fip->percentage && fip->rpm == 0) { /* Approximate RPM based on a 10,000 RPM Maximum */ fip->rpm = fip->percentage * 100; } } return rv; }
static int onlp_fan_hdr_get_locked__(onlp_oid_t oid, onlp_oid_hdr_t* hdr) { int rv = onlp_fani_hdr_get(oid, hdr); if(ONLP_SUCCESS(rv)) { return rv; } if(ONLP_UNSUPPORTED(rv)) { onlp_fan_info_t fi; rv = onlp_fani_info_get(oid, &fi); memcpy(hdr, &fi.hdr, sizeof(fi.hdr)); } return rv; }
static int onlp_fan_status_get_locked__(onlp_oid_t oid, uint32_t* status) { int rv = onlp_fani_status_get(oid, status); if(ONLP_SUCCESS(rv)) { return rv; } if(ONLP_UNSUPPORTED(rv)) { onlp_fan_info_t fi; rv = onlp_fani_info_get(oid, &fi); *status = fi.status; } return rv; }
int onlp_sysi_platform_manage_leds(void) { int rv; onlp_fan_info_t fi; onlp_led_mode_t mode = ONLP_LED_MODE_GREEN; rv = onlp_fani_info_get(ONLP_FAN_ID_CREATE(1), &fi); if(rv < 0) { mode = ONLP_LED_MODE_ORANGE; } else if((fi.status & 1) == 0) { mode = ONLP_LED_MODE_OFF; } else if(fi.status & ONLP_FAN_STATUS_FAILED) { mode = ONLP_LED_MODE_ORANGE; } onlp_ledi_mode_set(ONLP_LED_ID_CREATE(2), mode); onlp_psu_info_t pi; mode = ONLP_LED_MODE_GREEN; rv = onlp_psu_info_get(ONLP_PSU_ID_CREATE(1), &pi); if(rv < 0) { mode = ONLP_LED_MODE_ORANGE; } else if((pi.status & 1) == 0) { mode = ONLP_LED_MODE_OFF; } else if(pi.status & ONLP_PSU_STATUS_FAILED) { mode = ONLP_LED_MODE_ORANGE; } onlp_ledi_mode_set(ONLP_LED_ID_CREATE(4), mode); mode = ONLP_LED_MODE_GREEN; rv = onlp_psu_info_get(ONLP_PSU_ID_CREATE(2), &pi); if(rv < 0) { mode = ONLP_LED_MODE_ORANGE; } else if((pi.status & 1) == 0) { mode = ONLP_LED_MODE_OFF; } else if(pi.status & ONLP_PSU_STATUS_FAILED) { mode = ONLP_LED_MODE_ORANGE; } onlp_ledi_mode_set(ONLP_LED_ID_CREATE(5), mode); return 0; }
static int onlp_fan_present__(onlp_oid_t id, onlp_fan_info_t* info) { int rv; VALIDATE(id); /* Info retrieval required. */ rv = onlp_fani_info_get(id, info); if(rv < 0) { return rv; } /* The fan must be present. */ if((info->status & 0x1) == 0) { return ONLP_STATUS_E_MISSING; } return ONLP_STATUS_OK; }
int onlp_sysi_platform_manage_leds(void) { int rc,rc1; onlp_fan_info_t info1,info2; onlp_led_mode_t fan_new_mode; onlp_thermal_info_t ti; onlp_led_mode_t temp_new_mode; onlp_psu_info_t psu1; onlp_led_mode_t psu1_new_mode; onlp_psu_info_t psu2; onlp_led_mode_t psu2_new_mode; onlp_led_mode_t sys_new_mode; /*fan led */ rc=onlp_fani_info_get(ONLP_FAN_ID_CREATE(1), &info1); rc1=onlp_fani_info_get(ONLP_FAN_ID_CREATE(2), &info2); if ((rc != ONLP_STATUS_OK)||(rc1 != ONLP_STATUS_OK)){ fan_new_mode=ONLP_LED_MODE_RED; goto temp_led; } if(((info1.status&0x3)==1)&&((info2.status&0x3)==1)) fan_new_mode=ONLP_LED_MODE_GREEN; else fan_new_mode=ONLP_LED_MODE_RED; temp_led: onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN),fan_new_mode); /*temperature led */ rc = onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(1), &ti); if (rc != ONLP_STATUS_OK) { temp_new_mode=ONLP_LED_MODE_OFF; goto psu1_led; } if(ti.mcelsius >= 75000) temp_new_mode=ONLP_LED_MODE_RED; else temp_new_mode=ONLP_LED_MODE_GREEN; psu1_led: onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_TEMP),temp_new_mode); /*psu1 and psu2 led */ rc=onlp_psui_info_get(ONLP_PSU_ID_CREATE(1),&psu1); if (rc != ONLP_STATUS_OK) { psu1_new_mode=ONLP_LED_MODE_OFF; goto psu2_led; } if((psu1.status&0x1)&&!(psu1.status&0x2)) psu1_new_mode=ONLP_LED_MODE_GREEN; else psu1_new_mode=ONLP_LED_MODE_OFF; psu2_led: onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_PSU1),psu1_new_mode); //psu2 led ---------------- rc=onlp_psui_info_get(ONLP_PSU_ID_CREATE(2),&psu2); if (rc != ONLP_STATUS_OK) { psu2_new_mode=ONLP_LED_MODE_OFF; goto sys_led; } if((psu2.status&0x1)&&!(psu2.status&0x2)) psu2_new_mode=ONLP_LED_MODE_GREEN; else psu2_new_mode=ONLP_LED_MODE_OFF; sys_led : onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_PSU2),psu2_new_mode); //sys led ---------------- if((fan_new_mode!=ONLP_LED_MODE_GREEN)||((psu2_new_mode!=ONLP_LED_MODE_GREEN)&& \ (psu1_new_mode!=ONLP_LED_MODE_GREEN))) sys_new_mode=ONLP_LED_MODE_RED_BLINKING; else sys_new_mode=ONLP_LED_MODE_GREEN; onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_SYS),sys_new_mode); return ONLP_STATUS_OK; }
/* * 1. If any FAN failed, set all the other fans as full speed (100%) * 2. When (LM75-1 + LM75-2)/2 >= 49.5 C, set fan speed from 40% to 65%. * 3. When (LM75-1 + LM75-2)/2 >= 53C, set fan speed from 65% to 80% * 4. When (LM75-1 + LM75-2)/2 >= 57.7C, set fan speed from 80% to 100% * 5. When (LM75-1 + LM75-2)/2 <= 52.7C, set fan speed from 100% to 80% * 6. When (LM75-1 + LM75-2)/2 <= 47.7C, set fan speed from 80% to 65% * 7. When (LM75-1 + LM75-2)/2 <= 42.7C, set fan speed from 65% to 40% * 8. The default FAN speed is 40% */ int onlp_sysi_platform_manage_fans(void) { #define LEV1_UP_TEMP 57500 /*temperature*/ #define LEV1_DOWN_TEMP NULL /* unused */ #define LEV1_SPEED_PERC 100 /*percentage*/ #define LEV2_UP_TEMP 53000 #define LEV2_DOWN_TEMP 52700 #define LEV2_SPEED_PERC 80 #define LEV3_UP_TEMP 49500 #define LEV3_DOWN_TEMP 47700 #define LEV3_SPEED_PERC 65 #define LEV4_UP_TEMP NULL /* unused */ #define LEV4_DOWN_TEMP 42700 #define LEV4_SPEED_PERC 40 #define FAN_NUM_ON_MAIN_BROAD 5 int rc, i; int is_up; int new_temp, temp1, temp2, diff; static int new_perc = 0, ori_perc = 0; static int ori_temp = 0; onlp_thermal_info_t thermal_info; onlp_fan_info_t fan_info; /* get new temperature */ if ((rc = onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(1), &thermal_info)) != ONLP_STATUS_OK) goto _EXIT; temp1 = thermal_info.mcelsius; if ((rc = onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(2), &thermal_info)) != ONLP_STATUS_OK) goto _EXIT; temp2 = thermal_info.mcelsius; new_temp = (temp1+temp2)/2; /* check fan status */ for (i=1; i<=FAN_NUM_ON_MAIN_BROAD; i++) { if ((rc = onlp_fani_info_get(ONLP_FAN_ID_CREATE(i), &fan_info)) != ONLP_STATUS_OK) goto _EXIT; if (fan_info.status & ONLP_FAN_STATUS_FAILED) { new_perc = LEV1_SPEED_PERC; goto _CTRL; } } diff = new_temp - ori_temp; if (diff == 0) goto _EXIT; else is_up = (diff > 0 ? 1 : 0); if (is_up) { if (new_temp >= LEV1_UP_TEMP) new_perc = LEV1_SPEED_PERC; else if (new_temp >= LEV2_UP_TEMP) new_perc = LEV2_SPEED_PERC; else if (new_temp >= LEV3_UP_TEMP) new_perc = LEV3_SPEED_PERC; else new_perc = LEV4_SPEED_PERC; } else { if (new_temp <= LEV4_DOWN_TEMP) new_perc = LEV4_SPEED_PERC; else if (new_temp <= LEV3_DOWN_TEMP) new_perc = LEV3_SPEED_PERC; else if (new_temp <= LEV2_DOWN_TEMP) new_perc = LEV2_SPEED_PERC; else new_perc = LEV1_SPEED_PERC; } _CTRL : if (LOCAL_DEBUG) printf("\n[DEBUG][%s][%d]{ori:temp=%d, perc=%d} {new:temp=%d, perc=%d}\n", __FUNCTION__, __LINE__, ori_temp, ori_perc, new_temp, new_perc); if (ori_perc == new_perc) goto _EXIT; /* ctrl fans */ AIM_LOG_INFO("Fan Speeds are now at %d%%", new_perc); if ((rc = onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), new_perc)) != ONLP_STATUS_OK) goto _EXIT; /* update om */ ori_perc = new_perc; ori_temp = new_temp; _EXIT : return rc; }
/* * Front to Back * 1. When (LM75-1 + LM75-4)/2 >= 47.95 C, please set CPLD's registor 0xd from "0x08" to "0x0d". (40% to 65%). * 2. When (LM75-1 + LM75-4)/2 >= 49.65 C, please set CPLD's registor 0xd from "0x0d" to "0x10". (65% to 80%) * 3. When (LM75-1 + LM75-4)/2 >= 54.05C, please set CPLD's registor 0x0d from "0x10" to "0x14". (80% to 100%) * 4. When (LM75-1 + LM75-4)/2 <= 52.05C, please set CPLD's registor 0x0d from "0x14" to "0x10". (100% to 80%) * 5. When (LM75-1 + LM75-4)/2 <= 47.05C, please set CPLD's registor 0x0d from "0x10" to "0x0d". (80% to 65%) * 6. When (LM75-1 + LM75-4)/2 <= 42.05C, please set CPLD's registor 0x0d from "0x0d" to "0x08" (65% to 40%). * 7. If CPLD's (0x60 address) registor 0x0C is not equal "0x0", for example "0x1~0x1f", * please set CPLD's registor 0x0d to "0x14" (direct to 100%) <--- Due to FAN Failed occur. * 8. Default value for FAN speed is 40% which is CPLD's registor 0x0d value is "0x08". * Back to Front * 1. When (LM75-1 + LM75-4)/2 >= 40.85 C, please set CPLD's registor 0xd from "0x08" to "0x0d". (40% to 65%). * 2. When (LM75-1 + LM75-4)/2 >= 44.85 C, please set CPLD's registor 0xd from "0x0d" to "0x10". (65% to 80%) * 3. When (LM75-1 + LM75-4)/2 >= 47.4C, please set CPLD's registor 0x0d from "0x10" to "0x14". (80% to 100%) * 4. When (LM75-1 + LM75-4)/2 <= 45.4C, please set CPLD's registor 0x0d from "0x14" to "0x10". (100% to 80%) * 5. When (LM75-1 + LM75-4)/2 <= 40.4C, please set CPLD's registor 0x0d from "0x10" to "0x0d". (80% to 65%) * 6. When (LM75-1 + LM75-4)/2 <= 35.4C, please set CPLD's registor 0x0d from "0x0d" to "0x08" (65% to 40%). * 7. If CPLD's (0x60 address) registor 0x0C is not equal "0x0", for example "0x1~0x1f", * please set CPLD's registor 0x0d to "0x14" (direct to 100%) <--- Due to FAN Failed occur. * 8. Default value for FAN speed is 40% which is CPLD's registor 0x0d value is "0x08". */ int onlp_sysi_platform_manage_fans(void) { int i = 0, arr_size, avg_temp; fan_ctrl_policy_t *policy; int cur_duty_cycle, new_duty_cycle; onlp_thermal_info_t thermal_1, thermal_4; int fd, len; char buf[10] = {0}; /* 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", i); return ONLP_STATUS_E_INTERNAL; } /* Decision 1: Set fan as full speed if any fan is failed. */ if (!(fan_info.status & ONLP_FAN_STATUS_PRESENT) || fan_info.status & ONLP_FAN_STATUS_FAILED) { AIM_LOG_MSG("Setting max"); return onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MAX); } /* Get fan direction (Only get the first one since all fan direction are the same) */ if (i == 1) { if (fan_info.status & ONLP_FAN_STATUS_F2B) { policy = fan_ctrl_policy_f2b; arr_size = AIM_ARRAYSIZE(fan_ctrl_policy_f2b); } else { policy = fan_ctrl_policy_b2f; arr_size = AIM_ARRAYSIZE(fan_ctrl_policy_b2f); } } } /* Get current fan speed */ 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; } cur_duty_cycle = atoi(buf); /* Decision 2: If no matched fan speed is found from the policy, * use FAN_DUTY_CYCLE_MIN as default speed */ for (i = 0; i < arr_size; i++) { if (policy[i].duty_cycle != cur_duty_cycle) continue; break; } if (i == arr_size) { return onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_DUTY_CYCLE_MIN); } /* Get current temperature */ if (onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(1), &thermal_1) != ONLP_STATUS_OK || onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(4), &thermal_4) != ONLP_STATUS_OK) { AIM_LOG_ERROR("Unable to read thermal status"); return ONLP_STATUS_E_INTERNAL; } avg_temp = (thermal_1.mcelsius + thermal_4.mcelsius) / 2; /* Decision 3: Decide new fan speed depend on fan direction/current fan speed/temperature */ new_duty_cycle = cur_duty_cycle; if ((avg_temp >= policy[i].temp_up_adjust) && (cur_duty_cycle != FAN_DUTY_CYCLE_MAX)) { new_duty_cycle = policy[i+1].duty_cycle; } else if ((avg_temp <= policy[i].temp_down_adjust) && (cur_duty_cycle != FAN_DUTY_CYCLE_MIN)) { new_duty_cycle = policy[i-1].duty_cycle; } if (new_duty_cycle == cur_duty_cycle) { /* Duty cycle does not change, just return */ return ONLP_STATUS_OK; } return onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), new_duty_cycle); }
int onlp_sysi_platform_manage_leds(void) { int i,tray_i,rc; onlp_fan_info_t info; onlp_led_mode_t fan_new_mode; onlp_led_mode_t fan_tray_new_mode[3]; onlp_psu_info_t psu; onlp_led_mode_t psu_new_mode; onlp_led_mode_t sys_new_mode; onlp_led_mode_t locator_new_mode; /*fan led */ /*fan led */ for(tray_i=0;tray_i<3;tray_i++){ for(i=CHASSIS_FAN_COUNT-2*tray_i;i>=CHASSIS_FAN_COUNT-2*tray_i-1;i--){ rc=onlp_fani_info_get(ONLP_FAN_ID_CREATE(i), &info); if ((rc != ONLP_STATUS_OK) ||((info.status&0x1)!=1)){ fan_tray_new_mode[tray_i]=ONLP_LED_MODE_OFF; goto tray_next; } else{ if((info.status&0x2)==1){ fan_tray_new_mode[tray_i]=ONLP_LED_MODE_YELLOW; goto tray_next; } } } fan_tray_new_mode[tray_i]=ONLP_LED_MODE_GREEN; tray_next: continue; } onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN_TRAY0),fan_tray_new_mode[0]); onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN_TRAY1),fan_tray_new_mode[1]); onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN_TRAY2),fan_tray_new_mode[2]); if((fan_tray_new_mode[0]==ONLP_LED_MODE_GREEN)&&(fan_tray_new_mode[1]==ONLP_LED_MODE_GREEN)&& (fan_tray_new_mode[2]==ONLP_LED_MODE_GREEN)) fan_new_mode=ONLP_LED_MODE_GREEN; else if((fan_tray_new_mode[0]==ONLP_LED_MODE_OFF)||(fan_tray_new_mode[1]==ONLP_LED_MODE_OFF)|| (fan_tray_new_mode[2]==ONLP_LED_MODE_OFF)) fan_new_mode=ONLP_LED_MODE_YELLOW; else fan_new_mode=ONLP_LED_MODE_YELLOW_BLINKING; onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_FAN),fan_new_mode); /*psu1 and psu2 led */ for(i=1;i<=CHASSIS_PSU_COUNT;i++){ rc=onlp_psui_info_get(ONLP_PSU_ID_CREATE(i),&psu); if (rc != ONLP_STATUS_OK) { continue; } if((psu.status&0x1)&&!(psu.status&0x2)){ psu_new_mode=ONLP_LED_MODE_GREEN; goto sys_led; } } psu_new_mode=ONLP_LED_MODE_YELLOW_BLINKING; sys_led : onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_POWER),psu_new_mode); //sys led ---------------- if((fan_new_mode!=ONLP_LED_MODE_GREEN)||(psu_new_mode!=ONLP_LED_MODE_GREEN)) sys_new_mode=ONLP_LED_MODE_YELLOW_BLINKING; else sys_new_mode=ONLP_LED_MODE_GREEN; onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_SYS),sys_new_mode); locator_new_mode=ONLP_LED_MODE_BLUE; onlp_ledi_mode_set(ONLP_LED_ID_CREATE(LED_LOCATOR),locator_new_mode); return ONLP_STATUS_OK; }