diff --git a/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json index 44871c057e82..94592fa8cebc 100644 --- a/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dell_s6000_s1220-r0/pmon_daemon_control.json @@ -1,4 +1,3 @@ { - "skip_ledd": true, - "skip_thermalctld": true + "skip_ledd": true } diff --git a/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json b/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json index 44871c057e82..94592fa8cebc 100644 --- a/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json +++ b/device/dell/x86_64-dell_s6100_c2538-r0/pmon_daemon_control.json @@ -1,4 +1,3 @@ { - "skip_ledd": true, - "skip_thermalctld": true + "skip_ledd": true } diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py index 899754709bcc..ffad96de925f 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/chassis.py @@ -44,6 +44,8 @@ class Chassis(ChassisBase): def __init__(self): ChassisBase.__init__(self) + self.status_led_reg = "system_led" + self.supported_led_color = ['green', 'blinking green', 'amber', 'blinking amber'] # Initialize SFP list self.PORT_START = 0 self.PORT_END = 31 @@ -101,13 +103,30 @@ def _get_cpld_register(self, reg_name): try: with open(mb_reg_file, 'r') as fd: rv = fd.read() - except Exception as error: + except IOError: rv = 'ERR' rv = rv.rstrip('\r\n') rv = rv.lstrip(" ") return rv + def _set_cpld_register(self, reg_name, value): + # On successful write, returns the value will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR+'/'+reg_name + + if (not os.path.isfile(cpld_reg_file)): + return rv + + try: + with open(cpld_reg_file, 'w') as fd: + rv = fd.write(str(value)) + except IOError: + rv = 'ERR' + + return rv + def _nvram_write(self, offset, val): resource = "/dev/nvram" fd = os.open(resource, os.O_RDWR) @@ -179,6 +198,23 @@ def get_status(self): """ return True + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether Chassis is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_base_mac(self): """ Retrieves the base MAC address for the chassis @@ -305,4 +341,41 @@ def get_change_event(self, timeout=0): return True, ret_dict return False, ret_dict + def set_status_led(self, color): + """ + Sets the state of the system LED + Args: + color: A string representing the color with which to set the + system LED + + Returns: + bool: True if system LED state is set successfully, False if not + """ + if color not in self.supported_led_color: + return False + + # Change color string format to the one used by driver + color = color.replace('amber', 'yellow') + color = color.replace('blinking ', 'blink_') + rv = self._set_cpld_register(self.status_led_reg, color) + if (rv != 'ERR'): + return True + else: + return False + + def get_status_led(self): + """ + Gets the state of the system LED + + Returns: + A string, one of the valid LED color strings which could be vendor + specified. + """ + status_led = self._get_cpld_register(self.status_led_reg) + if (status_led != 'ERR'): + status_led = status_led.replace('yellow', 'amber') + status_led = status_led.replace('blink_', 'blinking ') + return status_led + else: + return None diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py index 1e21c233f5d8..d9459be47c4f 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/component.py @@ -29,8 +29,8 @@ class Component(ComponentBase): "booting")], ["System-CPLD", "Used for managing CPU board devices and power"], ["Master-CPLD", ("Used for managing Fan, PSU, system LEDs, QSFP " - "modules (1-16)")], - ["Slave-CPLD", "Used for managing QSFP modules (17-32)"] + "modules (17-32)")], + ["Slave-CPLD", "Used for managing QSFP modules (1-16)"] ] def __init__(self, component_index): @@ -90,6 +90,55 @@ def get_name(self): """ return self.name + def get_model(self): + """ + Retrieves the part number of the component + Returns: + string: Part number of component + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the component + Returns: + string: Serial number of component + """ + return 'NA' + + def get_presence(self): + """ + Retrieves the presence of the component + Returns: + bool: True if present, False if not + """ + return True + + def get_status(self): + """ + Retrieves the operational status of the component + Returns: + bool: True if component is operating properly, False if not + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether component is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_description(self): """ Retrieves the description of the component diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py index ef736089c44b..5afe0112441b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/eeprom.py @@ -36,8 +36,8 @@ ('Fab Rev', 's', 2) ] -# Fan eeprom fields in format required by EepromDecoder -fan_eeprom_format = [ +# FanTray eeprom fields in format required by EepromDecoder +fantray_eeprom_format = [ ('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7), ('Part Number', 's', 10), ('Part Num Revision', 's', 3), ('Mfg Test', 's', 2), ('Redundant copy', 's', 83), @@ -51,10 +51,10 @@ class Eeprom(TlvInfoDecoder): I2C_DIR = "/sys/class/i2c-adapter/" - def __init__(self, is_psu=False, psu_index=0, is_fan=False, fan_index=0): + def __init__(self, is_psu=False, psu_index=0, is_fantray=False, fantray_index=0): self.is_psu_eeprom = is_psu - self.is_fan_eeprom = is_fan - self.is_sys_eeprom = not (is_psu | is_fan) + self.is_fantray_eeprom = is_fantray + self.is_sys_eeprom = not (is_psu | is_fantray) if self.is_sys_eeprom: self.start_offset = 0 @@ -71,10 +71,10 @@ def __init__(self, is_psu=False, psu_index=0, is_fan=False, fan_index=0): + "i2c-1/1-005{}/eeprom".format(2 - self.index) self.format = psu_eeprom_format else: - self.index = fan_index + self.index = fantray_index self.eeprom_path = self.I2C_DIR \ + "i2c-11/11-005{}/eeprom".format(4 - self.index) - self.format = fan_eeprom_format + self.format = fantray_eeprom_format EepromDecoder.__init__(self, self.eeprom_path, self.format, self.start_offset, '', True) self._load_device_eeprom() diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py index fbdbf650db73..d5a4f379e90b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan.py @@ -13,7 +13,6 @@ import os import glob from sonic_platform_base.fan_base import FanBase - from sonic_platform.eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -25,33 +24,37 @@ class Fan(FanBase): """DellEMC Platform-specific Fan class""" - CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0/" I2C_DIR = "/sys/class/i2c-adapter/" - - def __init__(self, fan_index, psu_fan=False, dependency=None): + FAN_DEV_MAPPING = { + 1: {1: ("i2c-11/11-002a", 1), 2: ("i2c-11/11-002a", 2)}, + 2: {1: ("i2c-11/11-0029", 3), 2: ("i2c-11/11-0029", 4)}, + 3: {1: ("i2c-11/11-0029", 1), 2: ("i2c-11/11-0029", 2)} + } + + def __init__(self, fantray_index=1, fan_index=1, + psu_index=1, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan self.is_driver_initialized = True if not self.is_psu_fan: # Fan is 1-based in DellEMC platforms - self.index = fan_index + 1 - self.fan_presence_reg = "fan_prs" - self.fan_led_reg = "fan{}_led".format(fan_index) - self.get_fan_speed_reg = self.I2C_DIR + "i2c-11/11-0029/" +\ - "fan{}_input".format(self.index) - self.set_fan_speed_reg = self.I2C_DIR + "i2c-11/11-0029/" +\ - "fan{}_target".format(self.index) - self.eeprom = Eeprom(is_fan=True, fan_index=self.index) + self.fantray_index = fantray_index + self.index = fan_index + self.dependency = dependency + self.get_fan_speed_reg = self.I2C_DIR +\ + "{}/fan{}_input".format(*self.FAN_DEV_MAPPING[fantray_index][fan_index]) + self.set_fan_speed_reg = self.I2C_DIR +\ + "{}/fan{}_target".format(*self.FAN_DEV_MAPPING[fantray_index][fan_index]) self.max_fan_speed = MAX_S6000_FAN_SPEED - self.supported_led_color = ['off', 'green', 'amber'] else: - self.index = fan_index + self.psu_index = psu_index + self.index = 1 self.dependency = dependency self.set_fan_speed_reg = self.I2C_DIR +\ - "i2c-1/1-005{}/fan1_target".format(10 - self.index) + "i2c-1/1-005{}/fan1_target".format(10 - self.psu_index) hwmon_dir = self.I2C_DIR +\ - "i2c-1/1-005{}/hwmon/".format(10 - self.index) + "i2c-1/1-005{}/hwmon/".format(10 - self.psu_index) try: hwmon_node = os.listdir(hwmon_dir)[0] except OSError: @@ -61,43 +64,6 @@ def __init__(self, fan_index, psu_fan=False, dependency=None): self.get_fan_speed_reg = hwmon_dir + hwmon_node + '/fan1_input' self.max_fan_speed = MAX_S6000_PSU_FAN_SPEED - def _get_cpld_register(self, reg_name): - # On successful read, returns the value read from given - # reg_name and on failure returns 'ERR' - rv = 'ERR' - cpld_reg_file = self.CPLD_DIR + reg_name - - if (not os.path.isfile(cpld_reg_file)): - return rv - - try: - with open(cpld_reg_file, 'r') as fd: - rv = fd.read() - except: - rv = 'ERR' - - rv = rv.rstrip('\r\n') - rv = rv.lstrip(" ") - return rv - - def _set_cpld_register(self, reg_name, value): - # On successful write, returns the value will be written on - # reg_name and on failure returns 'ERR' - rv = 'ERR' - cpld_reg_file = self.CPLD_DIR + reg_name - - if (not os.path.isfile(cpld_reg_file)): - print("open error") - return rv - - try: - with open(cpld_reg_file, 'w') as fd: - rv = fd.write(str(value)) - except: - rv = 'ERR' - - return rv - def _get_i2c_register(self, reg_file): # On successful read, returns the value read from given # reg_name and on failure returns 'ERR' @@ -155,9 +121,9 @@ def get_name(self): string: The name of the Fan """ if not self.is_psu_fan: - return "FanTray{}-Fan1".format(self.index) + return "FanTray{}-Fan{}".format(self.fantray_index, self.index) else: - return "PSU{} Fan".format(self.index) + return "PSU{} Fan".format(self.psu_index) def get_presence(self): """ @@ -166,42 +132,23 @@ def get_presence(self): Returns: bool: True if Fan is present, False if not """ - status = False - if self.is_psu_fan: - return self.dependency.get_presence() - - fan_presence = self._get_cpld_register(self.fan_presence_reg) - if (fan_presence != 'ERR'): - fan_presence = int(fan_presence,16) & self.index - if fan_presence: - status = True - - return status + return self.dependency.get_presence() def get_model(self): """ Retrieves the part number of the Fan - Returns: string: Part number of Fan """ - if not self.is_psu_fan: - return self.eeprom.get_part_number() - else: - return 'NA' + return 'NA' def get_serial(self): """ Retrieves the serial number of the Fan - Returns: string: Serial number of Fan """ - # Sample Serial number format "US-01234D-54321-25A-0123-A00" - if not self.is_psu_fan: - return self.eeprom.get_serial_number() - else: - return 'NA' + return 'NA' def get_status(self): """ @@ -218,6 +165,23 @@ def get_status(self): return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether Fan is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_direction(self): """ Retrieves the fan airflow direction @@ -234,11 +198,10 @@ def get_direction(self): if self.is_psu_fan: direction = {1: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE, 3: self.FAN_DIRECTION_EXHAUST, 4: self.FAN_DIRECTION_INTAKE} - fan_direction = self.dependency.eeprom.airflow_fan_type() else: direction = {1: self.FAN_DIRECTION_EXHAUST, 2: self.FAN_DIRECTION_INTAKE} - fan_direction = self.eeprom.airflow_fan_type() + fan_direction = self.dependency.eeprom.airflow_fan_type() return direction.get(fan_direction, self.FAN_DIRECTION_NOT_APPLICABLE) def get_speed(self): @@ -282,8 +245,8 @@ def set_speed(self, speed): Returns: bool: True if set success, False if fail. """ - fan_set = (speed * self.max_fan_speed)/ 100 - rv = self._set_i2c_register(self.set_fan_speed_reg , fan_set) + fan_set = (speed * self.max_fan_speed) // 100 + rv = self._set_i2c_register(self.set_fan_speed_reg, fan_set) if (rv != 'ERR'): return True else: @@ -298,16 +261,9 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - if self.is_psu_fan or (color not in self.supported_led_color): - return False - if(color == self.STATUS_LED_COLOR_AMBER): - color = 'yellow' - - rv = self._set_cpld_register(self.fan_led_reg ,color) - if (rv != 'ERR'): - return True - else: - return False + # No LED available for FanTray and PSU Fan + # Return True to avoid thermalctld alarm. + return True def get_status_led(self): """ @@ -316,18 +272,8 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ - if self.is_psu_fan: - # No LED available for PSU Fan - return None - - fan_led = self._get_cpld_register(self.fan_led_reg) - if (fan_led != 'ERR'): - if (fan_led == 'yellow'): - return self.STATUS_LED_COLOR_AMBER - else: - return fan_led - else: - return self.STATUS_LED_COLOR_OFF + # No LED available for FanTray and PSU Fan + return None def get_target_speed(self): """ diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py index c8ea283e5ba4..19d7bc9d2269 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/fan_drawer.py @@ -9,26 +9,163 @@ ######################################################################## try: + import os + from sonic_platform_base.fan_drawer_base import FanDrawerBase + from sonic_platform.eeprom import Eeprom from sonic_platform.fan import Fan except ImportError as e: raise ImportError(str(e) + "- required module not found") +MAX_S6000_FANS_PER_FANTRAY = 2 + class FanDrawer(FanDrawerBase): - """DellEMC Platform-specific Fan class""" + """DellEMC Platform-specific Fan Drawer class""" - def __init__(self, fantray_index): + CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0/" + def __init__(self, fantray_index): FanDrawerBase.__init__(self) # FanTray is 1-based in DellEMC platforms - self.fantrayindex = fantray_index + 1 - self._fan_list.append(Fan(fantray_index)) + self.index = fantray_index + 1 + self.eeprom = Eeprom(is_fantray=True, fantray_index=self.index) + self.fantray_presence_reg = "fan_prs" + self.fantray_led_reg = "fan{}_led".format(self.index - 1) + self.supported_led_color = ['off', 'green', 'amber'] + + for i in range(1, MAX_S6000_FANS_PER_FANTRAY+1): + self._fan_list.append(Fan(fantray_index=self.index, fan_index=i, dependency=self)) + + def _get_cpld_register(self, reg_name): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR + reg_name + + if (not os.path.isfile(cpld_reg_file)): + return rv + + try: + with open(cpld_reg_file, 'r') as fd: + rv = fd.read() + except IOError: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _set_cpld_register(self, reg_name, value): + # On successful write, returns the value will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + cpld_reg_file = self.CPLD_DIR + reg_name + + if (not os.path.isfile(cpld_reg_file)): + return rv + + try: + with open(cpld_reg_file, 'w') as fd: + rv = fd.write(str(value)) + except IOError: + rv = 'ERR' + + return rv def get_name(self): """ - Retrieves the fan drawer name + Retrieves the Fandrawer name Returns: string: The name of the device """ - return "FanTray{}".format(self.fantrayindex) + return "FanTray{}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the Fandrawer + + Returns: + bool: True if Fandrawer is present, False if not + """ + presence = False + + fantray_presence = self._get_cpld_register(self.fantray_presence_reg) + if (fantray_presence != 'ERR'): + fantray_presence = int(fantray_presence, 16) & (1 << (self.index - 1)) + if fantray_presence: + presence = True + + return presence + + def get_model(self): + """ + Retrieves the part number of the Fandrawer + + Returns: + string: Part number of Fandrawer + """ + return self.eeprom.get_part_number() + + def get_serial(self): + """ + Retrieves the serial number of the Fandrawer + + Returns: + string: Serial number of Fandrawer + """ + # Sample Serial number format "US-01234D-54321-25A-0123-A00" + return self.eeprom.get_serial_number() + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this fan drawer is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fandrawer status LED + Returns: + bool: True if set success, False if fail. + """ + if color not in self.supported_led_color: + return False + if color == self.STATUS_LED_COLOR_AMBER: + color = 'yellow' + + rv = self._set_cpld_register(self.fantray_led_reg, color) + if (rv != 'ERR'): + return True + else: + return False + + def get_status_led(self): + """ + Gets the state of the fandrawer status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + fantray_led = self._get_cpld_register(self.fantray_led_reg) + if (fantray_led != 'ERR'): + if (fantray_led == 'yellow'): + return self.STATUS_LED_COLOR_AMBER + else: + return fantray_led + else: + return self.STATUS_LED_COLOR_OFF diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py index af52ccedbc44..7e2e478e54ee 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/psu.py @@ -53,7 +53,7 @@ def __init__(self, psu_index): self.eeprom = Eeprom(is_psu=True, psu_index=self.index) - self._fan_list.append(Fan(self.index, psu_fan=True, dependency=self)) + self._fan_list.append(Fan(psu_index=self.index, psu_fan=True, dependency=self)) def _get_cpld_register(self, reg_name): # On successful read, returns the value read from given @@ -171,6 +171,23 @@ def get_status(self): return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether PSU is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + def get_voltage(self): """ Retrieves current PSU voltage output diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py index 175e601dbe76..b66cb31ec96b 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/sfp.py @@ -10,6 +10,7 @@ try: import re + import struct import time from sonic_platform_base.sfp_base import SfpBase from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId @@ -27,6 +28,9 @@ DOM_OFFSET = 0 DOM_OFFSET1 = 384 +QSFP_CONTROL_OFFSET = 86 +QSFP_POWEROVERRIDE_OFFSET = 93 + cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -108,7 +112,7 @@ def __init__(self, index, sfp_type, eeprom_path, sfp_control, sfp_ctrl_idx): SfpBase.__init__(self) self.sfp_type = sfp_type - self.index = index + self.index = index + 1 self.eeprom_path = eeprom_path self.sfp_control = sfp_control self.sfp_ctrl_idx = sfp_ctrl_idx @@ -132,9 +136,10 @@ def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes): eeprom.close() return None + raw = bytearray(raw) try: for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) except BaseException: eeprom.close() return None @@ -588,40 +593,14 @@ def get_tx_disable_channel(self): """ Retrieves the TX disabled channels in this SFP """ - tx_disable = None - tx_disable_list = [] + tx_disable_channel = 0 - tx_disable_data = self._get_eeprom_data('tx_disable') - if (tx_disable_data is not None): - tx_disable = tx_disable_data['data']['Tx1Disable']['value'] - if (tx_disable == 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx2Disable']['value'] - if (tx_disable == 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx3Disable']['value'] - if (tx_disable == 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx4Disable']['value'] - if (tx_disable == 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - - bit4 = int(tx_disable_list[3]) * 8 - bit3 = int(tx_disable_list[2]) * 4 - bit2 = int(tx_disable_list[1]) * 2 - bit1 = int(tx_disable_list[0]) * 1 - - tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1) + tx_disable = self.get_tx_disable() + for channel, disable in enumerate(tx_disable): + if disable: + tx_disable_channel |= 1 << channel - return tx_disable_channel + return tx_disable_channel def get_lpmode(self): """ @@ -722,7 +701,6 @@ def get_rx_power(self): return rx_power_list - def get_tx_power(self): """ Retrieves the TX power of this SFP @@ -822,19 +800,68 @@ def tx_disable(self, tx_disable): """ Disable SFP TX for all channels """ - return False + eeprom = None + tx_disable_value = 0xf if tx_disable else 0x0 + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_CONTROL_OFFSET) + eeprom.write(struct.pack('B', tx_disable_value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def tx_disable_channel(self, channel, disable): """ Sets the tx_disable for specified SFP channels """ - return False + eeprom = None + current_state = self.get_tx_disable_channel() + + if disable: + tx_disable_value = current_state | channel + else: + tx_disable_value = current_state & (~channel) + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_CONTROL_OFFSET) + eeprom.write(struct.pack('B', tx_disable_value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def set_power_override(self, power_override, power_set): """ Sets SFP power level using power_override and power_set """ - return False + eeprom = None + power_override_bit = 0x1 if power_override else 0 + power_set_bit = 0x2 if power_set else 0 + value = power_override_bit | power_set_bit + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + eeprom.write(struct.pack('B', value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def get_status(self): """ @@ -848,3 +875,20 @@ def get_status(self): status = True return status + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py index 2f130ebabbb3..87f828d3d780 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6000/sonic_platform/thermal.py @@ -168,6 +168,23 @@ def get_status(self): else: return True + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether Thermal is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_temperature(self): """ Retrieves current temperature reading from thermal diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py index 47ef87b951db..7c4f5de2202d 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/chassis.py @@ -172,6 +172,23 @@ def get_status(self): """ return True + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether Chassis is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_base_mac(self): """ Retrieves the base MAC address for the chassis diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py index 6b1420a98606..bea180d440b5 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/component.py @@ -39,9 +39,10 @@ class Component(ComponentBase): ] def __init__(self, component_index=0, - is_module=False, iom_index=0, i2c_line=0): + is_module=False, iom_index=0, i2c_line=0, dependency=None): self.is_module_component = is_module + self.dependency = dependency if self.is_module_component: self.index = iom_index @@ -132,6 +133,61 @@ def get_name(self): """ return self.name + def get_model(self): + """ + Retrieves the part number of the component + Returns: + string: Part number of component + """ + return 'NA' + + def get_serial(self): + """ + Retrieves the serial number of the component + Returns: + string: Serial number of component + """ + return 'NA' + + def get_presence(self): + """ + Retrieves the presence of the component + Returns: + bool: True if present, False if not + """ + if self.is_module_component: + return self.dependency.get_presence() + else: + return True + + def get_status(self): + """ + Retrieves the operational status of the component + Returns: + bool: True if component is operating properly, False if not + """ + if self.is_module_component: + return self.dependency.get_status() + else: + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether component is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_description(self): """ Retrieves the description of the component diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py index 8404a8d2bf5f..5b3c8977ac0a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan.py @@ -26,30 +26,23 @@ class Fan(FanBase): HWMON_NODE = os.listdir(HWMON_DIR)[0] MAILBOX_DIR = HWMON_DIR + HWMON_NODE - def __init__(self, fantray_index=1, fan_index=1, psu_fan=False): + def __init__(self, fantray_index=1, psu_index=1, psu_fan=False, dependency=None): self.is_psu_fan = psu_fan if not self.is_psu_fan: - # API index is starting from 0, DellEMC platform index is starting - # from 1 - self.fantrayindex = fantray_index + 1 - self.fanindex = fan_index + 1 - self.fan_presence_reg = "fan{}_fault".format( - 2 * self.fantrayindex - 1) + self.fantrayindex = fantray_index + self.dependency = dependency self.fan_status_reg = "fan{}_alarm".format( 2 * self.fantrayindex - 1) self.get_fan_speed_reg = "fan{}_input".format( 2 * self.fantrayindex - 1) self.get_fan_dir_reg = "fan{}_airflow".format( 2 * self.fantrayindex - 1) - self.fan_serialno_reg = "fan{}_serialno".format( - 2 * self.fantrayindex - 1) self.max_fan_speed = MAX_S6100_FAN_SPEED else: - # PSU Fan index starts from 11 - self.fanindex = fan_index + 10 - self.fan_presence_reg = "fan{}_fault".format(self.fanindex) - self.get_fan_speed_reg = "fan{}_input".format(self.fanindex) - self.get_fan_dir_reg = "fan{}_airflow".format(self.fanindex) + self.psuindex = psu_index + self.fan_presence_reg = "fan{}_fault".format(self.psuindex + 10) + self.get_fan_speed_reg = "fan{}_input".format(self.psuindex + 10) + self.get_fan_dir_reg = "fan{}_airflow".format(self.psuindex + 10) self.max_fan_speed = MAX_S6100_PSU_FAN_SPEED def _get_pmc_register(self, reg_name): @@ -77,10 +70,9 @@ def get_name(self): string: The name of the device """ if not self.is_psu_fan: - return "FanTray{}-Fan{}".format( - self.fantrayindex, self.fanindex - 1) + return "FanTray{}-Fan1".format(self.fantrayindex) else: - return "PSU{} Fan".format(self.fanindex - 10) + return "PSU{} Fan".format(self.psuindex) def get_model(self): """ @@ -88,21 +80,7 @@ def get_model(self): Returns: string: Part number of FAN """ - # For Serial number "US-01234D-54321-25A-0123-A00", the part - # number is "01234D" - if self.is_psu_fan: - return 'NA' - - fan_serialno = self._get_pmc_register(self.fan_serialno_reg) - if (fan_serialno != 'ERR') and self.get_presence(): - if (len(fan_serialno.split('-')) > 1): - fan_partno = fan_serialno.split('-')[1] - else: - fan_partno = 'NA' - else: - fan_partno = 'NA' - - return fan_partno + return 'NA' def get_serial(self): """ @@ -110,15 +88,7 @@ def get_serial(self): Returns: string: Serial number of FAN """ - # Sample Serial number format "US-01234D-54321-25A-0123-A00" - if self.is_psu_fan: - return 'NA' - - fan_serialno = self._get_pmc_register(self.fan_serialno_reg) - if (fan_serialno == 'ERR') or not self.get_presence(): - fan_serialno = 'NA' - - return fan_serialno + return 'NA' def get_presence(self): """ @@ -126,14 +96,17 @@ def get_presence(self): Returns: bool: True if fan is present, False if not """ - status = False - fantray_presence = self._get_pmc_register(self.fan_presence_reg) - if (fantray_presence != 'ERR'): - fantray_presence = int(fantray_presence, 10) - if (~fantray_presence & 0b1): - status = True + if not self.is_psu_fan: + return self.dependency.get_presence() - return status + presence = False + fan_presence = self._get_pmc_register(self.fan_presence_reg) + if (fan_presence != 'ERR'): + fan_presence = int(fan_presence, 10) + if (~fan_presence & 0b1): + presence = True + + return presence def get_status(self): """ @@ -157,6 +130,23 @@ def get_status(self): return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return 1 + + def is_replaceable(self): + """ + Indicate whether Fan is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_direction(self): """ Retrieves the fan airflow direction @@ -216,7 +206,6 @@ def set_speed(self, speed): Returns: bool: True if set success, False if fail. """ - # Fan speeds are controlled by Smart-fussion FPGA. return False @@ -229,7 +218,7 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. """ - # Leds are controlled by Smart-fussion FPGA. + # No LED available for FanTray and PSU Fan # Return True to avoid thermalctld alarm. return True @@ -240,17 +229,8 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings. """ - if self.is_psu_fan: - # No LED available for PSU Fan - return None - else: - if self.get_presence(): - if self.get_status(): - return self.STATUS_LED_COLOR_GREEN - else: - return self.STATUS_LED_COLOR_AMBER - else: - return self.STATUS_LED_COLOR_OFF + # No LED available for FanTray and PSU Fan + return None def get_target_speed(self): """ @@ -262,5 +242,3 @@ def get_target_speed(self): # Fan speeds are controlled by Smart-fussion FPGA. # Return current speed to avoid false thermalctld alarm. return self.get_speed() - - diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py index ada5e93393c9..88782b2da298 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/fan_drawer.py @@ -9,6 +9,8 @@ ######################################################################## try: + import os + from sonic_platform_base.fan_drawer_base import FanDrawerBase from sonic_platform.fan import Fan except ImportError as e: @@ -16,14 +18,38 @@ class FanDrawer(FanDrawerBase): - """DellEMC Platform-specific Fan class""" + """DellEMC Platform-specific Fan Drawer class""" - def __init__(self, fantray_index): + HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" + HWMON_NODE = os.listdir(HWMON_DIR)[0] + MAILBOX_DIR = HWMON_DIR + HWMON_NODE + def __init__(self, fantray_index): FanDrawerBase.__init__(self) # FanTray is 1-based in DellEMC platforms - self.fantrayindex = fantray_index + 1 - self._fan_list.append(Fan(fantray_index)) + self.index = fantray_index + 1 + self.presence_reg = "fan{}_fault".format(2 * self.index - 1) + self.serialno_reg = "fan{}_serialno".format(2 * self.index - 1) + + self._fan_list.append(Fan(self.index, dependency=self)) + + def _get_pmc_register(self, reg_name): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + mb_reg_file = self.MAILBOX_DIR+'/'+reg_name + + if (not os.path.isfile(mb_reg_file)): + return rv + try: + with open(mb_reg_file, 'r') as fd: + rv = fd.read() + except Exception as error: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv def get_name(self): """ @@ -31,4 +57,96 @@ def get_name(self): Returns: string: The name of the device """ - return "FanTray{}".format(self.fantrayindex) + return "FanTray{}".format(self.index) + + def get_model(self): + """ + Retrieves the part number of Fandrawer + Returns: + string: Part number of Fandrawer + """ + # For Serial number "US-01234D-54321-25A-0123-A00", the part + # number is "01234D" + fantray_serialno = self._get_pmc_register(self.serialno_reg) + if (fantray_serialno != 'ERR') and self.get_presence(): + if (len(fantray_serialno.split('-')) > 1): + fantray_partno = fantray_serialno.split('-')[1] + else: + fantray_partno = 'NA' + else: + fantray_partno = 'NA' + + return fantray_partno + + def get_serial(self): + """ + Retrieves the serial number of Fandrawer + Returns: + string: Serial number of Fandrawer + """ + # Sample Serial number format "US-01234D-54321-25A-0123-A00" + fantray_serialno = self._get_pmc_register(self.serialno_reg) + if (fantray_serialno == 'ERR') or not self.get_presence(): + fantray_serialno = 'NA' + + return fantray_serialno + + def get_presence(self): + """ + Retrieves the presence of the Fandrawer + Returns: + bool: True if fan is present, False if not + """ + presence = False + fantray_presence = self._get_pmc_register(self.presence_reg) + if (fantray_presence != 'ERR'): + fantray_presence = int(fantray_presence, 10) + if (~fantray_presence & 0b1): + presence = True + + return presence + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this Fandrawer is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def set_status_led(self, color): + """ + Set led to expected color + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if set success, False if fail. + """ + # Leds are controlled by Smart-fussion FPGA. + # Return True to avoid thermalctld alarm. + return True + + def get_status_led(self): + """ + Gets the state of the Fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings. + """ + if self.get_presence(): + if self.get_fan(0).get_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + else: + return self.STATUS_LED_COLOR_OFF diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py index 6b93bcfd1fa7..923bb5c0550a 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py @@ -63,7 +63,7 @@ def __init__(self, module_index): self.iom_presence_reg = "iom_presence" component = Component(is_module=True, iom_index=self.index, - i2c_line=self.port_i2c_line) + i2c_line=self.port_i2c_line, dependency=self) self._component_list.append(component) eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/i2c-{1}/{1}-0050/eeprom" @@ -157,6 +157,23 @@ def get_status(self): return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether Module is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + def get_base_mac(self): """ Retrieves the base MAC address for the module diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py index 48b266daa278..8fd1a12bcfe0 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/psu.py @@ -40,7 +40,7 @@ def __init__(self, psu_index): self.psu_power_reg = "power4_input" # Passing True to specify it is a PSU fan - psu_fan = Fan(fan_index=self.index, psu_fan=True) + psu_fan = Fan(psu_index=self.index, psu_fan=True) self._fan_list.append(psu_fan) def _get_pmc_register(self, reg_name): @@ -232,3 +232,20 @@ def set_status_led(self, color): # In S6100, SmartFusion FPGA controls the PSU LED and the PSU # LED state cannot be changed from CPU. return False + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this PSU is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py index 6947b6cf2b66..0b242ab74d71 100755 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/sfp.py @@ -10,6 +10,7 @@ try: import re + import struct import time from sonic_platform_base.sfp_base import SfpBase from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId @@ -27,6 +28,9 @@ DOM_OFFSET = 0 DOM_OFFSET1 = 384 +QSFP_CONTROL_OFFSET = 86 +QSFP_POWEROVERRIDE_OFFSET = 93 + cable_length_tup = ('Length(km)', 'Length OM3(2m)', 'Length OM2(m)', 'Length OM1(m)', 'Length Cable Assembly(m)') @@ -107,7 +111,7 @@ def __init__(self, index, sfp_type, eeprom_path, sfp_control, sfp_ctrl_idx): SfpBase.__init__(self) self.sfp_type = sfp_type - self.index = index + self.index = index + 1 self.eeprom_path = eeprom_path self.sfp_control = sfp_control self.sfp_ctrl_idx = sfp_ctrl_idx @@ -131,9 +135,10 @@ def _read_eeprom_bytes(self, eeprom_path, offset, num_bytes): eeprom.close() return None + raw = bytearray(raw) try: for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) + eeprom_raw[n] = hex(raw[n])[2:].zfill(2) except BaseException: eeprom.close() return None @@ -594,40 +599,14 @@ def get_tx_disable_channel(self): """ Retrieves the TX disabled channels in this SFP """ - tx_disable = None - tx_disable_list = [] + tx_disable_channel = 0 - tx_disable_data = self._get_eeprom_data('tx_disable') - if (tx_disable_data is not None): - tx_disable = tx_disable_data['data']['Tx1Disable']['value'] - if (tx_disable == 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx2Disable']['value'] - if (tx_disable == 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx3Disable']['value'] - if (tx_disable == 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - tx_disable = tx_disable_data['data']['Tx4Disable']['value'] - if (tx_disable == 'On'): - tx_disable_list.append(1) - else: - tx_disable_list.append(0) - - bit4 = int(tx_disable_list[3]) * 8 - bit3 = int(tx_disable_list[2]) * 4 - bit2 = int(tx_disable_list[1]) * 2 - bit1 = int(tx_disable_list[0]) * 1 - - tx_disable_channel = hex(bit4 + bit3 + bit2 + bit1) + tx_disable = self.get_tx_disable() + for channel, disable in enumerate(tx_disable): + if disable: + tx_disable_channel |= 1 << channel - return tx_disable_channel + return tx_disable_channel def get_lpmode(self): """ @@ -836,19 +815,68 @@ def tx_disable(self, tx_disable): """ Disable SFP TX for all channels """ - return False + eeprom = None + tx_disable_value = 0xf if tx_disable else 0x0 + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_CONTROL_OFFSET) + eeprom.write(struct.pack('B', tx_disable_value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def tx_disable_channel(self, channel, disable): """ Sets the tx_disable for specified SFP channels """ - return False + eeprom = None + current_state = self.get_tx_disable_channel() + + if disable: + tx_disable_value = current_state | channel + else: + tx_disable_value = current_state & (~channel) + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_CONTROL_OFFSET) + eeprom.write(struct.pack('B', tx_disable_value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def set_power_override(self, power_override, power_set): """ Sets SFP power level using power_override and power_set """ - return False + eeprom = None + power_override_bit = 0x1 if power_override else 0 + power_set_bit = 0x2 if power_set else 0 + value = power_override_bit | power_set_bit + + try: + eeprom = open(self.eeprom_path, "r+b") + eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) + eeprom.write(struct.pack('B', value)) + except IOError: + return False + finally: + if eeprom is not None: + eeprom.close() + time.sleep(0.01) + + return True def get_status(self): """ @@ -862,3 +890,20 @@ def get_status(self): status = True return status + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py index f7037b000c5b..cac17f4b83aa 100644 --- a/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/thermal.py @@ -131,6 +131,23 @@ def get_status(self): return status + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + Returns: + integer: The 1-based relative physical position in parent + device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this Thermal is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + def get_temperature(self): """ Retrieves current temperature reading from thermal