From 5e00ec3e8f48c4cd62fdbb4846f930979b6956bd Mon Sep 17 00:00:00 2001 From: Brandon Chuang Date: Wed, 27 Jul 2022 17:40:37 +0800 Subject: [PATCH] [Edgecore][as4630_54te/as5835_54x] Fix wrong "show platform fan" status as4630_54te: 1. Fix wrong fan direction 2. Fix wrong get_status_led() 3. Fix wrong get_status() when psu power good failed as5835_54x: 1. Fix wrong get_status_led() 2. Fix wrong get_status() when psu power good failed 3. Fix wrong sysfs path of rear fan Signed-off-by: Brandon Chuang --- .../sonic_platform/fan.py | 45 +++++++--------- .../sonic_platform/fan_drawer.py | 24 ++++++++- .../sonic_platform/fan.py | 53 ++++++++++--------- .../sonic_platform/fan_drawer.py | 32 ++++++++++- 4 files changed, 100 insertions(+), 54 deletions(-) diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan.py index 8f48931244db..e145503551bf 100644 --- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan.py +++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan.py @@ -38,10 +38,6 @@ }, } - -FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R", - "FAN-3F", "FAN-3R"] - class Fan(FanBase): """Platform-specific Fan class""" @@ -63,7 +59,7 @@ def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): self.psu_cpld_path = I2C_PATH.format( self.psu_i2c_num, self.psu_i2c_addr) - FanBase.__init__(self) + FanBase.__init__(self) def get_direction(self): @@ -73,16 +69,14 @@ def get_direction(self): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - - if not self.is_psu_fan: dir_str = "{}{}{}".format(CPLD_FAN_I2C_PATH, 'direction_', self.fan_tray_index+1) val=self._api_helper.read_txt_file(dir_str) if val is not None: if int(val, 10)==0:#F2B - direction=self.FAN_DIRECTION_EXHAUST - else: direction=self.FAN_DIRECTION_INTAKE + else: + direction=self.FAN_DIRECTION_EXHAUST else: direction=self.FAN_DIRECTION_EXHAUST @@ -105,7 +99,7 @@ def get_speed(self): Returns: An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) - + """ speed = 0 if self.is_psu_fan: @@ -117,7 +111,7 @@ def get_speed(self): speed=100 else: return 0 - elif self.get_presence(): + elif self.get_presence(): speed_path = "{}{}".format(CPLD_FAN_I2C_PATH, 'duty_cycle_percentage') speed=self._api_helper.read_txt_file(speed_path) if speed is None: @@ -156,7 +150,7 @@ def set_speed(self, speed): A boolean, True if speed is set successfully, False if not """ - if not self.is_psu_fan and self.get_presence(): + if not self.is_psu_fan and self.get_presence(): speed_path = "{}{}".format(CPLD_FAN_I2C_PATH, 'duty_cycle_percentage') return self._api_helper.write_txt_file(speed_path, int(speed)) @@ -179,14 +173,13 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ - status=self.get_presence() - if status is None: - return self.STATUS_LED_COLOR_OFF + if self.is_psu_fan: + return None return { - 1: self.STATUS_LED_COLOR_GREEN, - 0: self.STATUS_LED_COLOR_RED - }.get(status, self.STATUS_LED_COLOR_OFF) + True: self.STATUS_LED_COLOR_GREEN, + False: self.STATUS_LED_COLOR_OFF + }.get(self.get_status(), self.STATUS_LED_COLOR_OFF) def get_name(self): """ @@ -194,11 +187,10 @@ def get_name(self): Returns: string: The name of the device """ - fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] \ - if not self.is_psu_fan \ - else "PSU-{} FAN-{}".format(self.psu_index+1, self.fan_index+1) + if self.is_psu_fan: + return "PSU-{} FAN-{}".format(self.psu_index+1, self.fan_index+1) - return fan_name + return "FAN-{}".format(self.fan_tray_index+1) def get_presence(self): """ @@ -206,8 +198,6 @@ def get_presence(self): Returns: bool: True if FAN is present, False if not """ - - if self.is_psu_fan: present_path="{}{}".format(self.psu_cpld_path, 'psu_present') else: @@ -226,6 +216,11 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ if self.is_psu_fan: + psu_fan_path = "{}{}".format(self.psu_cpld_path, 'psu_power_good') + val = self._api_helper.read_txt_file(psu_fan_path) + if val is None or int(val, 10)==0: + return False + psu_fan_path= "{}{}".format(self.psu_hwmon_path, 'psu_fan1_fault') val=self._api_helper.read_txt_file(psu_fan_path) if val is not None: @@ -268,7 +263,7 @@ def get_position_in_parent(self): integer: The 1-based relative physical position in parent device or -1 if cannot determine the position """ - return (self.fan_tray_index+1) \ + return (self.fan_index+1) \ if not self.is_psu_fan else (self.psu_index+1) def is_replaceable(self): diff --git a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan_drawer.py b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan_drawer.py index e21163c106c1..b4c2146b9f8b 100644 --- a/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan_drawer.py +++ b/device/accton/x86_64-accton_as4630_54te-r0/sonic_platform/fan_drawer.py @@ -10,7 +10,7 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -FANS_PER_FANTRAY = 2 +FANS_PER_FANTRAY = 1 class FanDrawer(FanDrawerBase): @@ -88,3 +88,25 @@ def is_replaceable(self): bool: True if it is replaceable. """ return True + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return False # Not supported + + def get_status_led(self): + """ + Gets the state of the fan status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return { + True: self.STATUS_LED_COLOR_GREEN, + False: self.STATUS_LED_COLOR_OFF + }.get(self.get_status(), self.STATUS_LED_COLOR_OFF) diff --git a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan.py b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan.py index 8cb1c17fdf72..43ce61559ad4 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan.py @@ -44,7 +44,7 @@ FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R", - "FAN-3F", "FAN-3R", "FAN-4F", "FAN-4R", + "FAN-3F", "FAN-3R", "FAN-4F", "FAN-4R", "FAN-5F", "FAN-5R"] class Fan(FanBase): @@ -61,7 +61,7 @@ def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): self.psu_i2c_addr = PSU_HWMON_I2C_MAPPING[self.psu_index]['addr'] self.psu_hwmon_path = I2C_PATH.format( self.psu_i2c_num, self.psu_i2c_addr) - + self.psu_i2c_num = PSU_CPLD_I2C_MAPPING[self.psu_index]['num'] self.psu_i2c_addr = PSU_CPLD_I2C_MAPPING[self.psu_index]['addr'] self.psu_cpld_path = I2C_PATH.format( @@ -77,7 +77,7 @@ def get_direction(self): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - + if not self.is_psu_fan: dir_str = "{}{}{}".format(CPLD_FAN_I2C_PATH, self.fan_tray_index+1, '_direction') @@ -91,17 +91,17 @@ def get_direction(self): direction=self.FAN_DIRECTION_EXHAUST else: #For PSU dir_str = "{}{}".format(self.psu_hwmon_path,'psu_fan_dir') - + val=self._api_helper.read_txt_file(dir_str) - if val is not None: + if val is not None: if val=='F2B': direction=self.FAN_DIRECTION_EXHAUST else: direction=self.FAN_DIRECTION_INTAKE else: direction=self.FAN_DIRECTION_EXHAUST - + return direction def get_speed(self): @@ -122,12 +122,12 @@ def get_speed(self): speed=100 else: return 0 - elif self.get_presence(): + elif self.get_presence(): speed_path = "{}{}".format(CPLD_FAN_I2C_PATH, '_duty_cycle_percentage') speed=self._api_helper.read_txt_file(speed_path) if speed is None: return 0 - + return int(speed) def get_target_speed(self): @@ -164,8 +164,8 @@ def set_speed(self, speed): A boolean, True if speed is set successfully, False if not """ - - if not self.is_psu_fan and self.get_presence(): + + if not self.is_psu_fan and self.get_presence(): speed_path = "{}{}".format(CPLD_FAN_I2C_PATH, '_duty_cycle_percentage') return self._api_helper.write_txt_file(speed_path, int(speed)) @@ -181,21 +181,20 @@ def set_status_led(self, color): bool: True if status LED state is set successfully, False if not """ return False #Not supported - + def get_status_led(self): """ Gets the state of the fan status LED Returns: A string, one of the predefined STATUS_LED_COLOR_* strings above """ - status=self.get_presence() - if status is None: - return self.STATUS_LED_COLOR_OFF + if self.is_psu_fan: + return None return { - 1: self.STATUS_LED_COLOR_GREEN, - 0: self.STATUS_LED_COLOR_RED - }.get(status, self.STATUS_LED_COLOR_OFF) + True: self.STATUS_LED_COLOR_GREEN, + False: self.STATUS_LED_COLOR_RED + }.get(self.get_status(), self.STATUS_LED_COLOR_RED) def get_name(self): """ @@ -208,20 +207,18 @@ def get_name(self): else "PSU-{} FAN-{}".format(self.psu_index+1, self.fan_index+1) return fan_name - + def get_presence(self): """ Retrieves the presence of the FAN Returns: bool: True if FAN is present, False if not """ - - if self.is_psu_fan: present_path="{}{}".format(self.psu_cpld_path, 'psu_present') else: present_path = "{}{}{}".format(CPLD_FAN_I2C_PATH, self.fan_tray_index+1, '_present') - + val=self._api_helper.read_txt_file(present_path) if val is not None: return int(val, 10)==1 @@ -235,30 +232,34 @@ def get_status(self): A boolean value, True if device is operating properly, False if not """ if self.is_psu_fan: + psu_path = "{}{}".format(self.psu_cpld_path, 'psu_power_good') + val = self._api_helper.read_txt_file(psu_path) + if val is None or int(val, 10)==0: + return False + psu_fan_path= "{}{}".format(self.psu_hwmon_path, 'psu_fan1_fault') val=self._api_helper.read_txt_file(psu_fan_path) if val is not None: return int(val, 10)==0 else: return False - else: - path = "{}{}{}".format(CPLD_FAN_I2C_PATH, self.fan_tray_index+1, '_fault') + else: + sys_index = self.fan_index * 10 + self.fan_tray_index+1 + path = "{}{}{}".format(CPLD_FAN_I2C_PATH, sys_index, '_fault') val=self._api_helper.read_txt_file(path) if val is not None: return int(val, 10)==0 else: return False - def get_model(self): """ Retrieves the model number (or part number) of the device Returns: string: Model/part number of device """ - return "N/A" - + def get_serial(self): """ Retrieves the serial number of the device diff --git a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan_drawer.py b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan_drawer.py index 17d339ee55f6..cc1e87337e16 100644 --- a/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan_drawer.py +++ b/device/accton/x86_64-accton_as5835_54x-r0/sonic_platform/fan_drawer.py @@ -22,7 +22,7 @@ def __init__(self, fantray_index): # FanTray is 0-based in platforms self.fantrayindex = fantray_index self.__initialize_fan_drawer() - + def __initialize_fan_drawer(self): from sonic_platform.fan import Fan @@ -67,7 +67,13 @@ def get_status(self): Returns: A boolean value, True if device is operating properly, False if not """ - return self._fan_list[0].get_status() + from sonic_platform.fan import Fan + + for fan in self._fan_list: + if not fan.get_status(): + return False + + return True def get_position_in_parent(self): """ @@ -88,3 +94,25 @@ def is_replaceable(self): bool: True if it is replaceable. """ return True + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return False # Not supported + + def get_status_led(self): + """ + Gets the state of the fan status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return { + True: self.STATUS_LED_COLOR_GREEN, + False: self.STATUS_LED_COLOR_RED + }.get(self.get_status(), self.STATUS_LED_COLOR_RED)