mirror of
https://github.com/Telecominfraproject/OpenNetworkLinux.git
synced 2025-11-02 19:28:18 +00:00
[as4600] Implement fan failure checking mechanism. [as5610] Implement thermal plan (#74)
* [as4600] Implement fan failure checking mechanism * [as5610] Implement thermal plan
This commit is contained in:
committed by
Steven Noble
parent
9ce34a3421
commit
72c18019a5
@@ -25,6 +25,7 @@
|
||||
***********************************************************/
|
||||
#include <onlp/platformi/fani.h>
|
||||
#include <onlplib/mmap.h>
|
||||
#include <unistd.h>
|
||||
//#include "onlpie_int.h"
|
||||
#include "platform_lib.h"
|
||||
|
||||
@@ -64,6 +65,7 @@
|
||||
|
||||
#define FAN_DUTY_CYCLE_MAX 0xFF
|
||||
#define PSU_FAN_RPM_MAX 15000
|
||||
#define FAN_FAILED_RETRY_COUNT 100
|
||||
|
||||
typedef struct onlp_fan_cpld
|
||||
{
|
||||
@@ -145,6 +147,71 @@ onlp_fan_info_t finfo[] = {
|
||||
},
|
||||
};
|
||||
|
||||
int _onlp_fani_get_operational_status(int fan_id, onlp_fan_info_t* info)
|
||||
{
|
||||
int rc = 0, i;
|
||||
unsigned char tach_low, tach_high, pwm_offset;
|
||||
unsigned char data[2] = {0};
|
||||
|
||||
if (fan_id < 1 || fan_id > 2) {
|
||||
return ONLP_STATUS_E_PARAM;
|
||||
}
|
||||
|
||||
if (fan_id == 1) {
|
||||
tach_low = I2C_FAN_1_STATUS_REG_TACH_1_LOW;
|
||||
tach_high = I2C_FAN_1_STATUS_REG_TACH_1_HIGH;
|
||||
}
|
||||
else {
|
||||
tach_low = I2C_FAN_2_STATUS_REG_TACH_3_LOW;
|
||||
tach_high = I2C_FAN_2_STATUS_REG_TACH_3_HIGH;
|
||||
}
|
||||
|
||||
for (i = 0; i < FAN_FAILED_RETRY_COUNT; i++) {
|
||||
/* Get the TACH status from ADT7473
|
||||
*/
|
||||
rc = I2C_nRead(1, I2C_SLAVE_ADDR_ADT7473, tach_low, 1, &data[0]);
|
||||
if (0 != rc) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
rc = I2C_nRead(1, I2C_SLAVE_ADDR_ADT7473, tach_high, 1, &data[1]);
|
||||
if (0 != rc) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
if (data[0] == 0xFF && data[1] == 0xFF) {
|
||||
/* Sleep 10 ms then retry if FAN fail
|
||||
*/
|
||||
info->status |= ONLP_FAN_STATUS_FAILED;
|
||||
usleep(10000);
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
info->status &= ~ONLP_FAN_STATUS_FAILED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set fan percentage and rpm by current PWM value
|
||||
* Based on the fan module data sheet, the max RPM of fan module is 23540
|
||||
* Since the RPM monitored from ADT7473 is not accurate, the RPM would be
|
||||
* reported in the formula: RPM = (Duty cycle) * 92314 / 1000.
|
||||
* We assume the RPM would be 23540 when duty cycle is 255.
|
||||
* So the multiplier is calculated from 23540/255 = 92.314
|
||||
*/
|
||||
pwm_offset = (fan_id == 1) ? I2C_FAN_1_DUTY_CYCLE_REG_PWM_1 :
|
||||
I2C_FAN_2_DUTY_CYCLE_REG_PWM_3 ;
|
||||
rc = I2C_nRead(1, I2C_SLAVE_ADDR_ADT7473, pwm_offset, 1, &data[0]);
|
||||
if (0 != rc) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
info->rpm = data[0] * 92314 / 1000;
|
||||
info->percentage = (data[0] * 100) / 255;
|
||||
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
int
|
||||
onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
|
||||
{
|
||||
@@ -160,11 +227,16 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
|
||||
switch (fid)
|
||||
{
|
||||
case 1: /* FAN 1 */
|
||||
case 2: /* FAN 2 */
|
||||
{
|
||||
unsigned char dir_mask = (fid == 1) ? CPLD_FAN_1_DIRECTION_BIT_MASK :
|
||||
CPLD_FAN_2_DIRECTION_BIT_MASK ;
|
||||
/* update the present status
|
||||
*/
|
||||
if ((val & fan_data[fid].cpld_mask) == fan_data[fid].cpld_mask)
|
||||
{
|
||||
info->status &= ~ONLP_FAN_STATUS_PRESENT;
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -174,7 +246,7 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
|
||||
/* Update the Direction
|
||||
* 0: Back to front. 1: Front to back.
|
||||
*/
|
||||
if((val & CPLD_FAN_1_DIRECTION_BIT_MASK) == CPLD_FAN_1_DIRECTION_BIT_MASK)
|
||||
if((val & dir_mask) == dir_mask)
|
||||
{
|
||||
info->status |= ONLP_FAN_STATUS_F2B;
|
||||
info->status &= ~ONLP_FAN_STATUS_B2F;
|
||||
@@ -185,107 +257,8 @@ onlp_fani_info_get(onlp_oid_t id, onlp_fan_info_t* info)
|
||||
info->status &= ~ONLP_FAN_STATUS_F2B;
|
||||
}
|
||||
|
||||
#if 0 /* Hardware issue, the rpm value is unstable.*/
|
||||
/* Get the information from I2C
|
||||
*/
|
||||
i2c_addr = I2C_SLAVE_ADDR_ADT7473;
|
||||
|
||||
/* Get the status
|
||||
*/
|
||||
rc = I2C_nRead(bus_id, i2c_addr, I2C_FAN_1_STATUS_REG_TACH_1_LOW, 1, &data[0]);
|
||||
if(0 != rc)
|
||||
{
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
rc = I2C_nRead(bus_id, i2c_addr, I2C_FAN_1_STATUS_REG_TACH_1_HIGH, 1, &data[1]);
|
||||
if(0 != rc)
|
||||
{
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
if (data[0] == 0xFF && data[1] == 0xFF)
|
||||
{
|
||||
/* FAN fail
|
||||
*/
|
||||
info->status |= ONLP_FAN_STATUS_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->status &= ~ONLP_FAN_STATUS_FAILED;
|
||||
}
|
||||
|
||||
/* Update the rpm, Fan Speed (RPM) = (90,000 * 60)/Fan TACH Reading
|
||||
*/
|
||||
fan_tach = data[1];
|
||||
fan_tach = (fan_tach << 8) + data[0];
|
||||
|
||||
if (fan_tach != 0)
|
||||
{
|
||||
info->rpm = (90000 * 60) / fan_tach;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 2: /* FAN 2 */
|
||||
if ((val & fan_data[fid].cpld_mask) == fan_data[fid].cpld_mask)
|
||||
{
|
||||
info->status &= ~ONLP_FAN_STATUS_PRESENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->status |= ONLP_FAN_STATUS_PRESENT;
|
||||
}
|
||||
|
||||
if((val & CPLD_FAN_2_DIRECTION_BIT_MASK) == CPLD_FAN_2_DIRECTION_BIT_MASK)
|
||||
{
|
||||
info->status |= ONLP_FAN_STATUS_F2B;
|
||||
info->status &= ~ONLP_FAN_STATUS_B2F;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->status |= ONLP_FAN_STATUS_B2F;
|
||||
info->status &= ~ONLP_FAN_STATUS_F2B;
|
||||
}
|
||||
|
||||
#if 0 /* Hardware issue, the rpm value is unstable.*/
|
||||
/* Get information from I2C
|
||||
*/
|
||||
i2c_addr = I2C_SLAVE_ADDR_ADT7473;
|
||||
|
||||
/* Get the status
|
||||
*/
|
||||
rc = I2C_nRead(bus_id, i2c_addr, I2C_FAN_2_STATUS_REG_TACH_3_LOW, 1, &data[0]);
|
||||
if(0 != rc)
|
||||
{
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
rc = I2C_nRead(bus_id, i2c_addr, I2C_FAN_2_STATUS_REG_TACH_3_HIGH, 1, &data[1]);
|
||||
if(0 != rc)
|
||||
{
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
if (data[0] == 0xFF && data[1] == 0xFF)
|
||||
{
|
||||
info->status |= ONLP_FAN_STATUS_FAILED;
|
||||
}
|
||||
else
|
||||
{
|
||||
info->status &= ~ONLP_FAN_STATUS_FAILED;
|
||||
}
|
||||
|
||||
/* Get the rpm, Fan Speed (RPM) = (90,000 * 60)/Fan TACH Reading
|
||||
*/
|
||||
fan_tach = data[1];
|
||||
fan_tach = (fan_tach << 8) + data[0];
|
||||
|
||||
if (fan_tach != 0)
|
||||
{
|
||||
info->rpm = (90000 * 60) / fan_tach;
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
||||
return _onlp_fani_get_operational_status(fid, info);
|
||||
}
|
||||
case 3: /* FAN in the PSU 1*/
|
||||
case 4: /* FAN in the PSU 2*/
|
||||
/* Get the PSU FAN status from CPLD
|
||||
@@ -524,5 +497,3 @@ onlp_fani_ioctl(onlp_oid_t id, va_list vargs)
|
||||
{
|
||||
return ONLP_STATUS_E_UNSUPPORTED;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -46,6 +46,9 @@
|
||||
#define CPLD_FAN_FAILURE_MASK 0x08
|
||||
#define CPLD_FAN_DIRECTION_MASK 0x10
|
||||
#define CPLD_FAN_SPEED_CTL_REG 0x0D
|
||||
#define CPLD_FAN_SPEED_VALUE_MAX 0x1F
|
||||
#define CPLD_FAN_SPEED_VALUE_MID 0x15
|
||||
#define CPLD_FAN_SPEED_VALUE_MIN 0x0C
|
||||
|
||||
#define I2C_PSU_BUS_ID 0
|
||||
#define I2C_PSU1_SLAVE_ADDR_CFG 0x3E
|
||||
@@ -76,8 +79,16 @@ typedef enum onlp_fan_id
|
||||
static int
|
||||
chassis_fan_cpld_val_to_duty_cycle(unsigned char reg_val)
|
||||
{
|
||||
if (reg_val >= 0x1F) {
|
||||
return 100;
|
||||
reg_val &= 0x1F;
|
||||
|
||||
if (reg_val == CPLD_FAN_SPEED_VALUE_MAX) {
|
||||
return FAN_PERCENTAGE_MAX;
|
||||
}
|
||||
else if (reg_val == CPLD_FAN_SPEED_VALUE_MID) {
|
||||
return FAN_PERCENTAGE_MID;
|
||||
}
|
||||
else if (reg_val == CPLD_FAN_SPEED_VALUE_MIN) {
|
||||
return FAN_PERCENTAGE_MIN;
|
||||
}
|
||||
|
||||
return (reg_val * 3.25);
|
||||
@@ -86,8 +97,14 @@ chassis_fan_cpld_val_to_duty_cycle(unsigned char reg_val)
|
||||
static int
|
||||
chassis_fan_duty_cycle_to_cpld_val(int duty_cycle)
|
||||
{
|
||||
if (duty_cycle >= 100) {
|
||||
return 0x1F;
|
||||
if (duty_cycle == FAN_PERCENTAGE_MAX) {
|
||||
return CPLD_FAN_SPEED_VALUE_MAX;
|
||||
}
|
||||
else if (duty_cycle == FAN_PERCENTAGE_MID) {
|
||||
return CPLD_FAN_SPEED_VALUE_MID;
|
||||
}
|
||||
else if (duty_cycle == FAN_PERCENTAGE_MIN) {
|
||||
return CPLD_FAN_SPEED_VALUE_MIN;
|
||||
}
|
||||
|
||||
return (duty_cycle / 3.25);
|
||||
@@ -110,6 +127,12 @@ onlp_fani_init(void)
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bring both fans to max.
|
||||
* These will be reduced after the first platform management sequence.
|
||||
*/
|
||||
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_PERCENTAGE_MAX);
|
||||
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
|
||||
@@ -63,4 +63,32 @@ typedef enum as5610_52x_psu_type {
|
||||
|
||||
as5610_52x_psu_type_t as5610_52x_get_psu_type(int id, char* modelname, int size);
|
||||
|
||||
enum onlp_thermal_id
|
||||
{
|
||||
THERMAL_RESERVED = 0,
|
||||
NE1617A_LOCAL_SENSOR,
|
||||
NE1617A_REMOTE_SENSOR,
|
||||
MAX6581_LOCAL_SENSOR,
|
||||
MAX6581_REMOTE_SENSOR_1,
|
||||
MAX6581_REMOTE_SENSOR_2,
|
||||
MAX6581_REMOTE_SENSOR_3,
|
||||
MAX6581_REMOTE_SENSOR_4,
|
||||
MAX6581_REMOTE_SENSOR_5,
|
||||
MAX6581_REMOTE_SENSOR_6,
|
||||
MAX6581_REMOTE_SENSOR_7,
|
||||
BCM56846_LOCAL_SENSOR,
|
||||
PSU1_THERMAL_SENSOR_1,
|
||||
PSU2_THERMAL_SENSOR_1,
|
||||
NUM_OF_CHASSIS_THERMAL_SENSOR = BCM56846_LOCAL_SENSOR,
|
||||
};
|
||||
|
||||
enum onlp_fan_duty_cycle_percentage
|
||||
{
|
||||
FAN_PERCENTAGE_MIN = 40,
|
||||
FAN_PERCENTAGE_MID = 70,
|
||||
FAN_PERCENTAGE_MAX = 100
|
||||
};
|
||||
|
||||
#define TEMPERATURE_MULTIPLIER 1000
|
||||
|
||||
#endif /* __PLATFORM_LIB_H__ */
|
||||
|
||||
@@ -95,7 +95,7 @@ psu_cpr_4011_info_get(onlp_psu_info_t* info)
|
||||
|
||||
/* Set the associated oid_table */
|
||||
info->hdr.coids[0] = ONLP_FAN_ID_CREATE(index + 1);
|
||||
info->hdr.coids[1] = ONLP_THERMAL_ID_CREATE(index + 8);
|
||||
info->hdr.coids[1] = ONLP_THERMAL_ID_CREATE(index + NUM_OF_CHASSIS_THERMAL_SENSOR);
|
||||
|
||||
/* Open channel for PSU
|
||||
*/
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
***********************************************************/
|
||||
#include <onlp/platformi/sysi.h>
|
||||
#include "powerpc_accton_as5610_52x_log.h"
|
||||
#include "platform_lib.h"
|
||||
|
||||
const char*
|
||||
onlp_sysi_platform_get(void)
|
||||
@@ -74,16 +75,18 @@ onlp_sysi_oids_get(onlp_oid_t* table, int max)
|
||||
/* 1 Fan */
|
||||
*e++ = ONLP_FAN_ID_CREATE(1);
|
||||
|
||||
/* 9 Thermal sensors */
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(1);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(2);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(3);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(4);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(5);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(6);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(7);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(8);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(11);
|
||||
/* 11 Thermal sensors */
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(NE1617A_LOCAL_SENSOR);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(NE1617A_REMOTE_SENSOR);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(MAX6581_LOCAL_SENSOR);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_1);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_2);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_3);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_4);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_5);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_6);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_7);
|
||||
*e++ = ONLP_THERMAL_ID_CREATE(BCM56846_LOCAL_SENSOR);
|
||||
|
||||
/* 5 LEDs */
|
||||
*e++ = ONLP_LED_ID_CREATE(1);
|
||||
@@ -95,13 +98,111 @@ onlp_sysi_oids_get(onlp_oid_t* table, int max)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The tA/tB/tC/tD/tCritical is defined in the thermal policy spec
|
||||
*/
|
||||
typedef struct temp_sensor_threshold {
|
||||
int tA;
|
||||
int tB;
|
||||
int tC;
|
||||
int tD;
|
||||
int tCitical;
|
||||
} temp_sensor_threshold_t;
|
||||
|
||||
/* The thermal plan table is for F2B(Front to back) airflow direction
|
||||
*/
|
||||
static const temp_sensor_threshold_t temp_sensor_threshold_f2b[NUM_OF_CHASSIS_THERMAL_SENSOR] = {
|
||||
{53, 46, 62, 67, 75}, {71, 63, 82, 86, 95}, {46, 38, 53, 58, 66}, {49, 42, 57, 62, 69},
|
||||
{59, 52, 70, 73, 81}, {57, 50, 65, 70, 77}, {49, 42, 57, 62, 70}, {47, 39, 55, 60, 69},
|
||||
{53, 46, 59, 65, 73}, {56, 48, 65, 69, 78}, {75, 71, 89, 94, 111}
|
||||
};
|
||||
|
||||
/* The thermal plan table is for B2F(Back to front) airflow direction
|
||||
*/
|
||||
static const temp_sensor_threshold_t temp_sensor_threshold_b2f[NUM_OF_CHASSIS_THERMAL_SENSOR] = {
|
||||
{58, 52, 73, 73, 80}, {63, 51, 67, 70, 84}, {43, 33, 47, 51, 63}, {49, 38, 56, 59, 69},
|
||||
{53, 47, 65, 68, 75}, {63, 57, 80, 78, 84}, {46, 37, 52, 55, 67}, {44, 34, 48, 52, 65},
|
||||
{55, 47, 65, 67, 76}, {47, 38, 53, 56, 68}, {81, 78, 99, 98, 104}
|
||||
};
|
||||
|
||||
#include <onlp/platformi/fani.h>
|
||||
#include <onlp/platformi/thermali.h>
|
||||
|
||||
int
|
||||
onlp_sysi_platform_manage_fans(void)
|
||||
{
|
||||
return ONLP_STATUS_E_UNSUPPORTED;
|
||||
int i = 0, rc;
|
||||
onlp_fan_info_t fi;
|
||||
const temp_sensor_threshold_t *pThreshold = NULL;
|
||||
onlp_thermal_info_t ti[NUM_OF_CHASSIS_THERMAL_SENSOR];
|
||||
int aboveTa = 0, aboveTb = 0, aboveTc = 0, aboveTd = 0, newPercentage = 0;
|
||||
|
||||
/* Get current fan status
|
||||
*/
|
||||
rc = onlp_fani_info_get(ONLP_FAN_ID_CREATE(1), &fi);
|
||||
if (rc < 0) {
|
||||
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_PERCENTAGE_MAX);
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
if (fi.status & ONLP_FAN_STATUS_FAILED) {
|
||||
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_PERCENTAGE_MAX);
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Bring fan speed to max if current speed is not expected
|
||||
*/
|
||||
if (fi.percentage != FAN_PERCENTAGE_MIN &&
|
||||
fi.percentage != FAN_PERCENTAGE_MID &&
|
||||
fi.percentage != FAN_PERCENTAGE_MAX ) {
|
||||
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_PERCENTAGE_MAX);
|
||||
return ONLP_STATUS_OK;
|
||||
}
|
||||
|
||||
/* Apply thermal plan by air flow direction
|
||||
*/
|
||||
pThreshold = (fi.status & ONLP_FAN_STATUS_F2B) ? temp_sensor_threshold_f2b :
|
||||
temp_sensor_threshold_b2f ;
|
||||
|
||||
/* Get temperature from each thermal sensor
|
||||
*/
|
||||
for (i = 0; i < NUM_OF_CHASSIS_THERMAL_SENSOR; i++) {
|
||||
rc = onlp_thermali_info_get(ONLP_THERMAL_ID_CREATE(i+1), &ti[i]);
|
||||
|
||||
if (rc != ONLP_STATUS_OK) {
|
||||
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), FAN_PERCENTAGE_MAX);
|
||||
return rc;
|
||||
}
|
||||
|
||||
aboveTa += (ti[i].mcelsius > pThreshold[i].tA* TEMPERATURE_MULTIPLIER) ? 1 : 0;
|
||||
aboveTb += (ti[i].mcelsius > pThreshold[i].tB* TEMPERATURE_MULTIPLIER) ? 1 : 0;
|
||||
aboveTc += (ti[i].mcelsius > pThreshold[i].tC* TEMPERATURE_MULTIPLIER) ? 1 : 0;
|
||||
aboveTd += (ti[i].mcelsius > pThreshold[i].tD* TEMPERATURE_MULTIPLIER) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* Adjust fan speed based on current temperature if fan speed changed
|
||||
*/
|
||||
if (fi.percentage == FAN_PERCENTAGE_MIN && aboveTc) {
|
||||
newPercentage = FAN_PERCENTAGE_MID;
|
||||
}
|
||||
else if (fi.percentage == FAN_PERCENTAGE_MID) {
|
||||
if (aboveTd) {
|
||||
newPercentage = FAN_PERCENTAGE_MAX;
|
||||
}
|
||||
else if (!aboveTb) {
|
||||
newPercentage = FAN_PERCENTAGE_MIN;
|
||||
}
|
||||
}
|
||||
else if (fi.percentage == FAN_PERCENTAGE_MAX && !aboveTa) {
|
||||
newPercentage = FAN_PERCENTAGE_MID;
|
||||
}
|
||||
|
||||
if (newPercentage != 0) {
|
||||
onlp_fani_percentage_set(ONLP_FAN_ID_CREATE(1), newPercentage);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#include <onlp/platformi/fani.h>
|
||||
#include <onlp/platformi/psui.h>
|
||||
#include <onlp/platformi/ledi.h>
|
||||
|
||||
@@ -156,6 +257,3 @@ onlp_sysi_platform_manage_leds(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -40,16 +40,9 @@
|
||||
#define I2C_REG_MAX6581_CONFIG 0x41
|
||||
#define I2C_MAX6581_REG_EXTENDED_RANGE_MASK 0x02
|
||||
|
||||
#define I2C_THERMAL_1_REG_ADT7473_LOCAL 0x26
|
||||
#define I2C_THERMAL_2_REG_ADT7473_REMOTE_1 0x25
|
||||
#define I2C_THERMAL_3_REG_ADT7473_REMOTE_2 0x27
|
||||
#define I2C_THERMAL_REG_ADT7473_EXTENDED 0x77
|
||||
|
||||
#define I2C_PSU1_SLAVE_ADDR_CFG 0x3E
|
||||
#define I2C_PSU2_SLAVE_ADDR_CFG 0x3D
|
||||
|
||||
#define TEMPERATURE_MULTIPLIER 1000
|
||||
|
||||
#define VALIDATE(_id) \
|
||||
do { \
|
||||
if(!ONLP_OID_IS_THERMAL(_id)) { \
|
||||
@@ -75,10 +68,10 @@ static int
|
||||
thermal_sensor_max6581_info_get(onlp_thermal_info_t* info)
|
||||
{
|
||||
unsigned char data = 0;
|
||||
unsigned char temp_reg[7] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x8};
|
||||
unsigned char temp_reg_dp[7] = {0x9, 0x52, 0x53, 0x54, 0x55, 0x56, 0x58}; /* Register to read decimal place */
|
||||
unsigned char temp_reg[8] = { 0x7, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x8};
|
||||
unsigned char temp_reg_dp[8] = {0x57, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x58}; /* Register to read decimal place */
|
||||
int base_degree = thermal_sensor_max6581_base_degree();
|
||||
int index = ONLP_OID_ID_GET(info->hdr.id) - 1;
|
||||
int index = ONLP_OID_ID_GET(info->hdr.id) - MAX6581_LOCAL_SENSOR;
|
||||
|
||||
/* Set the thermal status from diode fault(0x46) register */
|
||||
if (i2c_nRead(I2C_THERMAL_SENSOR_BUS_ID, I2C_SLAVE_ADDR_MAX6581, 0x46, sizeof(data), &data) != 0) {
|
||||
@@ -112,8 +105,10 @@ static int
|
||||
thermal_sensor_ne1617a_info_get(onlp_thermal_info_t* info)
|
||||
{
|
||||
unsigned char data = 0;
|
||||
unsigned char temp_reg[2] = {0x0, 0x1};
|
||||
int index = ONLP_OID_ID_GET(info->hdr.id) - NE1617A_LOCAL_SENSOR;
|
||||
|
||||
if (i2c_nRead(I2C_THERMAL_SENSOR_BUS_ID, I2C_SLAVE_ADDR_NE1617A, 0x1, sizeof(data), &data) != 0) {
|
||||
if (i2c_nRead(I2C_THERMAL_SENSOR_BUS_ID, I2C_SLAVE_ADDR_NE1617A, temp_reg[index], sizeof(data), &data) != 0) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
|
||||
@@ -130,10 +125,10 @@ thermal_sensor_cpr_4011_info_get(onlp_thermal_info_t* info)
|
||||
unsigned char status = 0;
|
||||
unsigned char i2c_addr;
|
||||
|
||||
if (ONLP_OID_ID_GET(info->hdr.id) == 9) {
|
||||
if (ONLP_OID_ID_GET(info->hdr.id) == PSU1_THERMAL_SENSOR_1) {
|
||||
i2c_addr = I2C_PSU1_SLAVE_ADDR_CFG;
|
||||
}
|
||||
else {
|
||||
else { /* PSU2_THERMAL_SENSOR_1 */
|
||||
i2c_addr = I2C_PSU2_SLAVE_ADDR_CFG;
|
||||
}
|
||||
|
||||
@@ -194,42 +189,48 @@ onlp_thermali_init(void)
|
||||
/* Static values */
|
||||
static onlp_thermal_info_t tinfo[] = {
|
||||
{ }, /* Not used */
|
||||
{ { ONLP_THERMAL_ID_CREATE(1), "Chassis Thermal Sensor 1 (near right-upper side of CPU)", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(NE1617A_LOCAL_SENSOR), "Chassis Thermal Sensor 1 (NE1617A local sensor)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(2), "Chassis Thermal Sensor 2 (near right side of MAX6581)", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(NE1617A_REMOTE_SENSOR), "Chassis Thermal Sensor 2 (the left middle side of the system)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(3), "Chassis Thermal Sensor 3 (near right side of MAC(Trident+)", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(MAX6581_LOCAL_SENSOR), "Chassis Thermal Sensor 3 (MAX6581 local sensor)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(4), "Chassis Thermal Sensor 4 (near left down side of Equalizer_U57)", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_1), "Chassis Thermal Sensor 4 (near right-upper side of CPU)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(5), "Chassis Thermal Sensor 5 (near right down side of MAC)", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_2), "Chassis Thermal Sensor 5 (near right side of MAX6581)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(6), "Chassis Thermal Sensor 6 (near upper side of Equalizer_U49)", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_3), "Chassis Thermal Sensor 6 (near right side of MAC(Trident+)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(7), "Chassis Thermal Sensor 7 (near left down side of PCB)", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_4), "Chassis Thermal Sensor 7 (near left down side of Equalizer_U57)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(8), "Chassis Thermal Sensor 8 (inside CPU)", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_5), "Chassis Thermal Sensor 8 (near right down side of MAC)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(9), "PSU-1 Thermal Sensor 1", ONLP_PSU_ID_CREATE(1)}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_6), "Chassis Thermal Sensor 9 (near upper side of Equalizer_U49)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(10), "PSU-2 Thermal Sensor 1", ONLP_PSU_ID_CREATE(2)}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(MAX6581_REMOTE_SENSOR_7), "Chassis Thermal Sensor 10 (near left down side of PCB)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(11), "Switch Thermal Sensor", 0}, 0x1,
|
||||
{ { ONLP_THERMAL_ID_CREATE(BCM56846_LOCAL_SENSOR), "Chassis Thermal Sensor 11 (BCM56846 local sensor)", 0}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(PSU1_THERMAL_SENSOR_1), "PSU-1 Thermal Sensor 1", ONLP_PSU_ID_CREATE(1)}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
},
|
||||
{ { ONLP_THERMAL_ID_CREATE(PSU2_THERMAL_SENSOR_1), "PSU-2 Thermal Sensor 1", ONLP_PSU_ID_CREATE(2)}, 0x1,
|
||||
ONLP_THERMAL_CAPS_ALL, 0, ONLP_THERMAL_THRESHOLD_INIT_DEFAULTS
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
/*
|
||||
* Retrieve the information structure for the given thermal OID.
|
||||
*
|
||||
* If the OID is invalid, return ONLP_E_STATUS_INVALID.
|
||||
@@ -246,8 +247,29 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
|
||||
VALIDATE(id);
|
||||
*info = tinfo[ONLP_OID_ID_GET(id)]; /* Set the ID/Description/Present state */
|
||||
|
||||
if (ONLP_OID_ID_GET(id) == BCM56846_LOCAL_SENSOR) {
|
||||
/* Switch Thermal Sensor */
|
||||
char* fname = "/var/run/broadcom/temp0";
|
||||
int rv = onlp_file_read_int(&info->mcelsius, fname);
|
||||
if(rv >= 0) {
|
||||
/** Present and running */
|
||||
info->status |= 1;
|
||||
ret = ONLP_STATUS_OK;
|
||||
}
|
||||
else if(rv == ONLP_STATUS_E_MISSING) {
|
||||
/** No switch management process running. */
|
||||
info->status = 0;
|
||||
ret = ONLP_STATUS_OK;
|
||||
}
|
||||
else {
|
||||
/** Other error. */
|
||||
ret = ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Read the temperature and status */
|
||||
if (ONLP_OID_ID_GET(id) >= 1 && ONLP_OID_ID_GET(id) <= 7) {
|
||||
if (ONLP_OID_ID_GET(id) >= MAX6581_LOCAL_SENSOR && ONLP_OID_ID_GET(id) <= MAX6581_REMOTE_SENSOR_7) {
|
||||
/* Set multiplexer to the channel of thermal sensor */
|
||||
if (as5610_52x_i2c0_pca9548_channel_set(0x80) != 0) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
@@ -256,7 +278,7 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
|
||||
ret = thermal_sensor_max6581_info_get(info);
|
||||
}
|
||||
|
||||
if (ONLP_OID_ID_GET(id) == 8) {
|
||||
if (ONLP_OID_ID_GET(id) == NE1617A_LOCAL_SENSOR || ONLP_OID_ID_GET(id) == NE1617A_REMOTE_SENSOR) {
|
||||
/* Set multiplexer to the channel of thermal sensor */
|
||||
if (as5610_52x_i2c0_pca9548_channel_set(0x80) != 0) {
|
||||
return ONLP_STATUS_E_INTERNAL;
|
||||
@@ -265,9 +287,10 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
|
||||
ret = thermal_sensor_ne1617a_info_get(info);
|
||||
}
|
||||
|
||||
if (ONLP_OID_ID_GET(id) == 9 || ONLP_OID_ID_GET(id) == 10) {
|
||||
if (ONLP_OID_ID_GET(id) == PSU1_THERMAL_SENSOR_1 || ONLP_OID_ID_GET(id) == PSU2_THERMAL_SENSOR_1) {
|
||||
/* Check PSU type */
|
||||
as5610_52x_psu_type_t psu_type = as5610_52x_get_psu_type(ONLP_OID_ID_GET(id)-8, NULL, 0);
|
||||
as5610_52x_psu_type_t psu_type;
|
||||
psu_type = as5610_52x_get_psu_type(ONLP_OID_ID_GET(id)-NUM_OF_CHASSIS_THERMAL_SENSOR, NULL, 0);
|
||||
|
||||
if (PSU_TYPE_AC_F2B == psu_type || PSU_TYPE_AC_B2F == psu_type) {
|
||||
/* Set multiplexer to the channel of thermal sensor */
|
||||
@@ -279,26 +302,6 @@ onlp_thermali_info_get(onlp_oid_t id, onlp_thermal_info_t* info)
|
||||
}
|
||||
}
|
||||
|
||||
if (ONLP_OID_ID_GET(id) == 11) {
|
||||
/* Switch Thermal Sensor */
|
||||
char* fname = "/var/run/broadcom/temp0";
|
||||
int rv = onlp_file_read_int(&info->mcelsius, fname);
|
||||
if(rv >= 0) {
|
||||
/** Present and running */
|
||||
info->status |= 1;
|
||||
ret = 0;
|
||||
}
|
||||
else if(rv == ONLP_STATUS_E_MISSING) {
|
||||
/** No switch management process running. */
|
||||
info->status = 0;
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
/** Other error. */
|
||||
ret = ONLP_STATUS_E_INTERNAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close PSU channel
|
||||
*/
|
||||
as5610_52x_i2c0_pca9548_channel_set(0);
|
||||
|
||||
Reference in New Issue
Block a user