platform/broadcom/sonic-platform-modules-dell/s6100/sonic_platform/module.py (108 lines of code) (raw):

#!/usr/bin/env python ######################################################################## # DellEMC S6100 # # Module contains an implementation of SONiC Platform Base API and # provides the Modules' information which are available in the platform # ######################################################################## try: import os from sonic_platform_base.module_base import ModuleBase from sonic_platform.sfp import Sfp from sonic_platform.component import Component from sonic_platform.eeprom import Eeprom except ImportError as e: raise ImportError(str(e) + "- required module not found") class Module(ModuleBase): """DellEMC Platform-specific Module class""" HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/" HWMON_NODE = os.listdir(HWMON_DIR)[0] MAILBOX_DIR = HWMON_DIR + HWMON_NODE IOM_I2C_MAPPING = { 1: 14, 2: 16, 3: 15, 4: 17 } EEPROM_I2C_MAPPING = { # IOM 1 0: [6, 66], 1: [6, 67], 2: [6, 68], 3: [6, 69], 4: [6, 70], 5: [6, 71], 6: [6, 72], 7: [6, 73], 8: [6, 74], 9: [6, 75], 10: [6, 76], 11: [6, 77], 12: [6, 78], 13: [6, 79], 14: [6, 80], 15: [6, 81], # IOM 2 16: [8, 34], 17: [8, 35], 18: [8, 36], 19: [8, 37], 20: [8, 38], 21: [8, 39], 22: [8, 40], 23: [8, 41], 24: [8, 42], 25: [8, 43], 26: [8, 44], 27: [8, 45], 28: [8, 46], 29: [8, 47], 30: [8, 48], 31: [8, 49], # IOM 3 32: [7, 50], 33: [7, 51], 34: [7, 52], 35: [7, 53], 36: [7, 54], 37: [7, 55], 38: [7, 56], 39: [7, 57], 40: [7, 58], 41: [7, 59], 42: [7, 60], 43: [7, 61], 44: [7, 62], 45: [7, 63], 46: [7, 64], 47: [7, 65], # IOM 4 48: [9, 18], 49: [9, 19], 50: [9, 20], 51: [9, 21], 52: [9, 22], 53: [9, 23], 54: [9, 24], 55: [9, 25], 56: [9, 26], 57: [9, 27], 58: [9, 28], 59: [9, 29], 60: [9, 30], 61: [9, 31], 62: [9, 32], 63: [9, 33] } def __init__(self, module_index): ModuleBase.__init__(self) # Modules are 1-based in DellEMC platforms self.index = module_index + 1 self.port_start = (self.index - 1) * 16 self.port_end = (self.index * 16) - 1 self.port_i2c_line = self.IOM_I2C_MAPPING[self.index] self._eeprom = Eeprom(iom_eeprom=True, i2c_line=self.port_i2c_line) self.iom_status_reg = "iom_status" self.iom_presence_reg = "iom_presence" component = Component(is_module=True, iom_index=self.index, 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" sfp_ctrl_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-003e/" # sfp.py will read eeprom contents and retrive the eeprom data. # It will also provide support sfp controls like reset and setting # low power mode. for index in range(self.port_start, self.port_end + 1): eeprom_path = eeprom_base.format(self.EEPROM_I2C_MAPPING[index][0], self.EEPROM_I2C_MAPPING[index][1]) sfp_control = sfp_ctrl_base.format(self.port_i2c_line) sfp_node = Sfp(index, 'QSFP', eeprom_path, sfp_control, index) self._sfp_list.append(sfp_node) 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): """ Retrieves the name of the device Returns: string: The name of the device """ return "IOM{}: {}".format(self.index, self._eeprom.modelstr()) def get_presence(self): """ Retrieves the presence of the Module Returns: bool: True if Module is present, False if not """ status = False iom_presence = self._get_pmc_register(self.iom_presence_reg) if (iom_presence != 'ERR'): iom_presence = int(iom_presence,16) if (~iom_presence & (1 << (self.index - 1))): status = True return status def get_model(self): """ Retrieves the part number of the module Returns: string: part number of module """ return self._eeprom.part_number_str() def get_serial(self): """ Retrieves the serial number of the module Returns: string: Serial number of module """ return self._eeprom.serial_str() def get_status(self): """ Retrieves the operational status of the Module Returns: bool: True if Module is operating properly, False if not """ status = False iom_status = self._get_pmc_register(self.iom_status_reg) if (iom_status != 'ERR'): iom_status = int(iom_status,16) if (~iom_status & (1 << (self.index - 1))): 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 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 Returns: A string containing the MAC address in the format 'XX:XX:XX:XX:XX:XX' """ # In S6100, individual modules doesn't have MAC address return '00:00:00:00:00:00' def get_system_eeprom_info(self): """ Retrieves the full content of system EEPROM information for the module Returns: A dictionary where keys are the type code defined in OCP ONIE TlvInfo EEPROM format and values are their corresponding values. Ex. { ‘0x21’:’AG9064’, ‘0x22’:’V1.0’, ‘0x23’:’AG9064-0109867821’, ‘0x24’:’001c0f000fcd0a’, ‘0x25’:’02/03/2018 16:22:00’, ‘0x26’:’01’, ‘0x27’:’REV01’, ‘0x28’:’AG9064-C2358-16G’} """ return self._eeprom.system_eeprom_info() def get_description(self): """ Retrieves the platform vendor's product description of the module Returns: A string, providing the vendor's product description of the module. """ return self._eeprom.modelstr() def get_slot(self): """ Retrieves the platform vendor's slot number of the module Returns: An integer, indicating the slot number in the chassis """ return self.index def get_oper_status(self): """ Retrieves the operational status of the module Returns: A string, the operational status of the module from one of the predefined status values: MODULE_STATUS_EMPTY, MODULE_STATUS_OFFLINE, MODULE_STATUS_FAULT, MODULE_STATUS_PRESENT or MODULE_STATUS_ONLINE """ if self.get_presence(): if self.get_status(): return self.MODULE_STATUS_ONLINE else: return self.MODULE_STATUS_PRESENT else: return self.MODULE_STATUS_EMPTY def get_maximum_consumed_power(self): """ Retrives the maximum power drawn by this module Returns: A float, with value of the maximum consumable power of the module. """ return 97.23