diff --git a/ixr7220h4-32d/scripts/h4_32d_platform_init.sh b/ixr7220h4-32d/scripts/h4_32d_platform_init.sh index 72f1088..91b0ae1 100644 --- a/ixr7220h4-32d/scripts/h4_32d_platform_init.sh +++ b/ixr7220h4-32d/scripts/h4_32d_platform_init.sh @@ -143,4 +143,10 @@ if [ "$dev" == "68" ]; then echo pcf8523 0x68 > /sys/bus/i2c/devices/i2c-1/new_device fi +# RTC +if decode-syseeprom | grep -q "Device Version 0x26 1 1"; then + modprobe rtc-pcf85363 + echo pcf85363 0x51 > /sys/bus/i2c/devices/i2c-1/new_device +fi + exit 0 diff --git a/ixr7220h5-32d/scripts/h5_32d_platform_init.sh b/ixr7220h5-32d/scripts/h5_32d_platform_init.sh index e8fa75b..bbfa829 100644 --- a/ixr7220h5-32d/scripts/h5_32d_platform_init.sh +++ b/ixr7220h5-32d/scripts/h5_32d_platform_init.sh @@ -148,4 +148,10 @@ do sleep 0.1 done +# RTC +if decode-syseeprom | grep -q "Device Version 0x26 1 1"; then + modprobe rtc-pcf85363 + echo pcf85363 0x51 > /sys/bus/i2c/devices/i2c-0/new_device +fi + exit 0 diff --git a/ixr7220h5-64d/scripts/h5_64d_platform_init.sh b/ixr7220h5-64d/scripts/h5_64d_platform_init.sh old mode 100755 new mode 100644 index 9679f8f..e44fdce --- a/ixr7220h5-64d/scripts/h5_64d_platform_init.sh +++ b/ixr7220h5-64d/scripts/h5_64d_platform_init.sh @@ -160,4 +160,11 @@ check_voltage() { check_voltage 1 check_voltage 2 + +# RTC +if decode-syseeprom | grep -q "Device Version 0x26 1 1"; then + modprobe rtc-pcf85363 + echo pcf85363 0x51 > /sys/bus/i2c/devices/i2c-0/new_device +fi + exit 0 diff --git a/ixr7220h5-64o/scripts/h5_64o_platform_init.sh b/ixr7220h5-64o/scripts/h5_64o_platform_init.sh index b2ba7ea..32814d9 100644 --- a/ixr7220h5-64o/scripts/h5_64o_platform_init.sh +++ b/ixr7220h5-64o/scripts/h5_64o_platform_init.sh @@ -171,4 +171,11 @@ retimer() { } retimer + +# RTC +if decode-syseeprom | grep -q "Device Version 0x26 1 1"; then + modprobe rtc-pcf85363 + echo pcf85363 0x51 > /sys/bus/i2c/devices/i2c-0/new_device +fi + exit 0 diff --git a/ixr7220h6-64/modules/h6_fan_cpld.c b/ixr7220h6-64/modules/h6_fan_cpld.c index 421c52e..cceef2d 100644 --- a/ixr7220h6-64/modules/h6_fan_cpld.c +++ b/ixr7220h6-64/modules/h6_fan_cpld.c @@ -51,6 +51,10 @@ static ssize_t reg_read(struct device *dev, struct device_attribute *da, char *buf); static ssize_t reg_write(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t show_fan_ctrl_mode(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_ctrl_mode(struct device *dev, struct device_attribute *da, const char *buf, size_t count); +static ssize_t show_fan_watchdog(struct device *dev, struct device_attribute *da, char *buf); +static ssize_t set_fan_watchdog(struct device *dev, struct device_attribute *da, const char *buf, size_t count); /* fan related data, the index should match sysfs_fan_attributes */ @@ -58,7 +62,10 @@ static const u8 fan_reg[] = { 0x00, /* fan pcb information */ 0x01, /* fan cpld major version */ 0x02, /* fan cpld minor version */ + 0x06, /* fan PWM debug mode*/ 0x08, /* fan 0-3 present status */ + 0x0a, /* fan watchdog 1 */ + 0x0b, /* fan watchdog 2 */ 0x0e, /* fan 0-3 led */ 0x10, /* front fan 0 pwm */ 0x11, /* rear fan 0 pwm */ @@ -100,7 +107,10 @@ enum sysfs_fan_attributes { FAN_PCB_REG, FAN_MAJOR_VERSION_REG, FAN_MINOR_VERSION_REG, + FAN_PWM_DEBUG_MODE, FAN_PRESENT_REG, + FAN_WATCHDOG_1, + FAN_WATCHDOG_2, FAN_LED_REG, FAN1_FRONT_PWM_REG, FAN1_REAR_PWM_REG, @@ -190,6 +200,10 @@ enum fan_led_light_mode { #define DECLARE_FAN_PCB_VERSION_ATTR() &sensor_dev_attr_pcb_version.dev_attr.attr +static SENSOR_DEVICE_ATTR(fan_ctrl_mode, S_IRUGO | S_IWUSR, show_fan_ctrl_mode, set_fan_ctrl_mode, 0); +static SENSOR_DEVICE_ATTR(fan_wd1, S_IRUGO | S_IWUSR, show_fan_watchdog, set_fan_watchdog, 0); +static SENSOR_DEVICE_ATTR(fan_wd2, S_IRUGO | S_IWUSR, show_fan_watchdog, set_fan_watchdog, 1); + #define DECLARE_FAN_ACCESS_SENSOR_DEV_ATTR() \ static SENSOR_DEVICE_ATTR(access, S_IWUSR | S_IRUGO, reg_read, reg_write, FAN_ACCESS) @@ -212,12 +226,18 @@ static struct attribute *h6_fan_attributes[] = { DECLARE_FAN_FW_VERSION_ATTR(), DECLARE_FAN_PCB_VERSION_ATTR(), DECLARE_FAN_ACCESS_ATTR(), + &sensor_dev_attr_fan_ctrl_mode.dev_attr.attr, + &sensor_dev_attr_fan_wd1.dev_attr.attr, + &sensor_dev_attr_fan_wd2.dev_attr.attr, NULL }; -#define FAN_DUTY_CYCLE_REG_MASK 0xF -#define FAN_MAX_DUTY_CYCLE 100 -#define FAN_REG_VAL_TO_SPEED_RPM_STEP 150 +#define FAN_DUTY_CYCLE_REG_MASK 0xF +#define FAN_MAX_DUTY_CYCLE 100 +#define FAN_REG_VAL_TO_SPEED_RPM_STEP 150 +#define FAN_SWCTL_MASK 0x1 +#define FAN_WDG_MASK 0x1 + static int h6_fan_read_value(struct i2c_client *client, u8 reg) { @@ -528,6 +548,66 @@ static struct h6_fan_data *h6_fan_update_device(struct device return data; } +static ssize_t show_fan_ctrl_mode(struct device *dev, struct device_attribute *da, char *buf) +{ + struct h6_fan_data *data = dev_get_drvdata(dev); + u8 val = 0; + + val = h6_fan_read_value(data->client, fan_reg[FAN_PWM_DEBUG_MODE]); + + return sprintf(buf, "%d\n", (val & FAN_SWCTL_MASK) ? 1:0); +} + +static ssize_t set_fan_ctrl_mode(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct h6_fan_data *data = dev_get_drvdata(dev); + u8 usr_val = 0; + + int ret = kstrtou8(buf, 10, &usr_val); + if (ret != 0) { + return ret; + } + if (usr_val > 1) { + return -EINVAL; + } + + h6_fan_write_value(data->client, fan_reg[FAN_PWM_DEBUG_MODE], usr_val & FAN_SWCTL_MASK); + + return count; +} + +static ssize_t show_fan_watchdog(struct device *dev, struct device_attribute *da, char *buf) +{ + struct h6_fan_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(da); + u8 val = 0; + + val = h6_fan_read_value(data->client, fan_reg[FAN_WATCHDOG_1 + sda->index]); + + return sprintf(buf, "%d\n", (val & FAN_WDG_MASK) ? 1:0); +} + +static ssize_t set_fan_watchdog(struct device *dev, struct device_attribute *da, const char *buf, size_t count) +{ + struct h6_fan_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(da); + + u8 usr_val = 0; + + int ret = kstrtou8(buf, 10, &usr_val); + if (ret != 0) { + return ret; + } + + if (usr_val > 1) { + return -EINVAL; + } + + h6_fan_write_value(data->client, fan_reg[FAN_WATCHDOG_1 + sda->index], usr_val & FAN_WDG_MASK); + + return count; +} + static int h6_fan_probe(struct i2c_client *client) { struct h6_fan_data *data; diff --git a/ixr7220h6-64/scripts/h6_64_platform_init.sh b/ixr7220h6-64/scripts/h6_64_platform_init.sh index 86b601c..672cb10 100755 --- a/ixr7220h6-64/scripts/h6_64_platform_init.sh +++ b/ixr7220h6-64/scripts/h6_64_platform_init.sh @@ -125,6 +125,17 @@ else echo "SYSEEPROM file not found" fi +echo 1 > /sys/bus/i2c/devices/79-0033/hwmon/hwmon*/fan_ctrl_mode +echo 1 > /sys/bus/i2c/devices/80-0033/hwmon/hwmon*/fan_ctrl_mode + +echo 1 > /sys/bus/i2c/devices/79-0033/hwmon/hwmon*/fan_wd1 +echo 1 > /sys/bus/i2c/devices/80-0033/hwmon/hwmon*/fan_wd1 + +echo 1 > /sys/bus/i2c/devices/79-0033/hwmon/hwmon5/fan_wd2 +echo 0 > /sys/bus/i2c/devices/79-0033/hwmon/hwmon5/fan_wd2 +echo 1 > /sys/bus/i2c/devices/80-0033/hwmon/hwmon5/fan_wd2 +echo 0 > /sys/bus/i2c/devices/80-0033/hwmon/hwmon5/fan_wd2 + h6-64_profile exit diff --git a/ixr7220h6-64/service/h6_64_platform_init.service b/ixr7220h6-64/service/h6_64_platform_init.service index b4cd5dc..c6d227a 100755 --- a/ixr7220h6-64/service/h6_64_platform_init.service +++ b/ixr7220h6-64/service/h6_64_platform_init.service @@ -1,7 +1,7 @@ [Unit] Description=Nokia-IXR7220-H6-64 Platform Service After=sysinit.target -Before=pmon.service determine-reboot-cause.service +Before=database.service determine-reboot-cause.service [Service] Type=oneshot diff --git a/ixr7220h6-64/sonic_platform/fan_drawer.py b/ixr7220h6-64/sonic_platform/fan_drawer.py index 4ce3816..81d12a3 100755 --- a/ixr7220h6-64/sonic_platform/fan_drawer.py +++ b/ixr7220h6-64/sonic_platform/fan_drawer.py @@ -40,6 +40,8 @@ def __init__(self, index): self.eeprom_dir = f"/sys/bus/i2c/devices/{EEPROM_ADDR[index]}-0050" self.new_eeprom_cmd = f"echo 24c64 0x50 > /sys/bus/i2c/devices/i2c-{EEPROM_ADDR[index]}/new_device" self.del_eeprom_cmd = f"echo 0x50 > /sys/bus/i2c/devices/i2c-{EEPROM_ADDR[index]}/delete_device" + self.watchdog_file = hwmon_path[0] + "fan_wd2" + self.feed_watchdog_cmd = f"echo 1 > {self.watchdog_file};echo 0 > {self.watchdog_file}" def get_index(self): """ @@ -191,6 +193,10 @@ def get_position_in_parent(self): """ return self._index + def feed_fan_watchdog(self): + if os.path.exists(self.watchdog_file): + os.system(self.feed_watchdog_cmd) + class RealDrawer(NokiaFanDrawer): """ For Nokia platforms with fan drawer(s) diff --git a/ixr7220h6-64/sonic_platform/psu.py b/ixr7220h6-64/sonic_platform/psu.py index a8d1791..ad86158 100755 --- a/ixr7220h6-64/sonic_platform/psu.py +++ b/ixr7220h6-64/sonic_platform/psu.py @@ -90,7 +90,7 @@ def get_model(self): string: Part number of PSU """ if self.get_presence(): - return read_sysfs_file(self.eeprom_dir+"product_name") + return read_sysfs_file(self.eeprom_dir+"part_number") return 'N/A' @@ -102,7 +102,7 @@ def get_serial(self): string: Serial number of PSU """ if self.get_presence(): - return read_sysfs_file(self.eeprom_dir+"serial_number") + return read_sysfs_file(self.eeprom_dir+"customer_sn") return 'N/A' diff --git a/ixr7220h6-64/sonic_platform/thermal_actions.py b/ixr7220h6-64/sonic_platform/thermal_actions.py index e7d9452..019383a 100755 --- a/ixr7220h6-64/sonic_platform/thermal_actions.py +++ b/ixr7220h6-64/sonic_platform/thermal_actions.py @@ -135,11 +135,19 @@ def execute(self, thermal_info_dict): :param thermal_info_dict: A dictionary stores all thermal information. :return: """ - from .thermal_infos import ThermalInfo + from .thermal_infos import ThermalInfo,FanInfo if ThermalInfo.INFO_NAME in thermal_info_dict and \ isinstance(thermal_info_dict[ThermalInfo.INFO_NAME], ThermalInfo): thermal_info_obj = thermal_info_dict[ThermalInfo.INFO_NAME] + + if FanInfo.INFO_NAME in thermal_info_dict and isinstance(thermal_info_dict[FanInfo.INFO_NAME], FanInfo): + fan_info_obj = thermal_info_dict[FanInfo.INFO_NAME] + if fan_info_obj.last_fan_slow_start_enable: + ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.threshold1_speed) + sonic_logger.log_warning(f"Fan slow start for the last fan insertion speed {self.threshold1_speed}") + return + if thermal_info_obj.is_set_fan_high_temp_speed(): ThermalRecoverAction.set_all_fan_speed(thermal_info_dict, self.hightemp_speed) elif thermal_info_obj.is_set_fan_threshold_two_speed(): diff --git a/ixr7220h6-64/sonic_platform/thermal_infos.py b/ixr7220h6-64/sonic_platform/thermal_infos.py index 4aa231d..a2aead7 100755 --- a/ixr7220h6-64/sonic_platform/thermal_infos.py +++ b/ixr7220h6-64/sonic_platform/thermal_infos.py @@ -1,11 +1,14 @@ try: + import time from sonic_platform_base.sonic_thermal_control.thermal_info_base import ThermalPolicyInfoBase from sonic_platform_base.sonic_thermal_control.thermal_json_object import thermal_json_object from sonic_py_common.logger import Logger except ImportError as e: raise ImportError(str(e) + ' - required module not found') from e -logger = Logger() +sonic_logger = Logger('fan_info') +sonic_logger.set_min_log_priority_info() +LAST_FAN_SOFT_START_DELAY_TIME = 18 @thermal_json_object('fan_info') class FanInfo(ThermalPolicyInfoBase): @@ -19,6 +22,9 @@ def __init__(self): self._absence_fans = set() self._presence_fans = set() self._status_changed = False + self.pre_presence_fan_num = 0 + self.last_fan_timestamp = 0 + self.last_fan_slow_start_enable = False def collect(self, chassis): """ @@ -27,7 +33,8 @@ def collect(self, chassis): :return: """ self._status_changed = False - for fan in chassis.get_all_fans(): + fans = chassis.get_all_fans() + for fan in fans: if fan.get_presence() and fan not in self._presence_fans: self._presence_fans.add(fan) self._status_changed = True @@ -39,6 +46,28 @@ def collect(self, chassis): if fan in self._presence_fans: self._presence_fans.remove(fan) + fan_total_num = len(fans) + fan_presence_num = len(self._presence_fans) + if fan_presence_num == fan_total_num and (self.pre_presence_fan_num == fan_total_num - 2 or self.pre_presence_fan_num == fan_total_num - 4): + self.last_fan_timestamp = time.time() + sonic_logger.log_info(f"The last fan drawer(s) inserted.") + + self.pre_presence_fan_num = fan_presence_num + + current_time = time.time() + + if current_time - self.last_fan_timestamp >= LAST_FAN_SOFT_START_DELAY_TIME and self.last_fan_timestamp != 0: + self.last_fan_timestamp = 0 + sonic_logger.log_warning(f"The last_fan_timestamp is cleared to 0 after {LAST_FAN_SOFT_START_DELAY_TIME} seconds.") + self.last_fan_slow_start_enable = (self.last_fan_timestamp > 0) + + drawers = chassis.get_all_fan_drawers() + if len(drawers) > 1: + if drawers[0].get_presence(): + drawers[0].feed_fan_watchdog() + if drawers[1].get_presence(): + drawers[1].feed_fan_watchdog() + def get_absence_fans(self): """ Retrieves absence fans diff --git a/ixr7250x1b/service/ixr7250x1b_platform_init.service b/ixr7250x1b/service/ixr7250x1b_platform_init.service index d99a606..a464b4f 100644 --- a/ixr7250x1b/service/ixr7250x1b_platform_init.service +++ b/ixr7250x1b/service/ixr7250x1b_platform_init.service @@ -1,7 +1,7 @@ [Unit] Description=Nokia-7250-IXR-X1b Platform Service After=sysinit.target -Before=determine-reboot-cause.service +Before=determine-reboot-cause.service database.service [Service] Type=oneshot