From bec0abb41611147ba0b251ef9cd5e765083715c8 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Mon, 2 Mar 2020 15:56:47 +0000 Subject: [PATCH 1/4] [mellanox]: Align platform API: change CPLD version representation. Signed-off-by: Nazarii Hnydyn --- .../sonic_platform/component.py | 124 +++++++++++------- 1 file changed, 78 insertions(+), 46 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index dc09ae4011fa..705513299bef 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -18,6 +18,11 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") +EMPTY = '' +ZERO = '0' +COMMA = ',' +NEWLINE = '\n' + #components definitions COMPONENT_BIOS = "BIOS" COMPONENT_CPLD = "CPLD" @@ -25,6 +30,7 @@ class Component(ComponentBase): def __init__(self): self.name = None + self.description = None self.image_ext_name = None @@ -38,17 +44,30 @@ def get_name(self): return self.name - def _read_generic_file(self, filename, len): + def get_description(self): + """ + Retrieves the description of the component + + Returns: + A string containing the description of the component + """ + return self.description + + + def _read_generic_file(self, filename, len, ignore_errors=True): """ Read a generic file, returns the contents of the file """ - result = '' + result = None + try: with io.open(filename, 'r') as fileobj: result = fileobj.read(len) - return result except IOError as e: - raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + if not ignore_errors: + raise RuntimeError("Failed to read file {} due to {}".format(filename, repr(e))) + + return result def _get_command_result(self, cmdline): @@ -83,6 +102,10 @@ def _check_file_validity(self, image_path): class ComponentBIOS(Component): + COMPONENT_NAME = 'BIOS' + COMPONENT_DESCRIPTION = 'BIOS - Basic Input/Output System' + COMPONENT_FIRMWARE_EXTENSION = '.rom' + # To update BIOS requires the ONIE with version 5.2.0016 or upper ONIE_VERSION_PARSE_PATTERN = '[0-9]{4}\.[0-9]{2}-([0-9]+)\.([0-9]+)\.([0-9]+)' ONIE_VERSION_MAJOR_OFFSET = 1 @@ -103,18 +126,9 @@ class ComponentBIOS(Component): BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' def __init__(self): - self.name = COMPONENT_BIOS - self.image_ext_name = ".rom" - - - def get_description(self): - """ - Retrieves the description of the component - - Returns: - A string containing the description of the component - """ - return "BIOS - Basic Input/Output System" + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION def get_firmware_version(self): @@ -210,34 +224,35 @@ def install_firmware(self, image_path): print("ERROR: Installing BIOS failed due to {}".format(repr(e))) return False - print("INFO: Reboot is required to finish BIOS installation.") + print("INFO: Reboot is required to finish BIOS installation") return True class ComponentCPLD(Component): - CPLD_VERSION_FILE_PATTERN = '/var/run/hw-management/system/cpld[0-9]_version' - CPLD_VERSION_MAX_LENGTH = 4 - - CPLD_UPDATE_COMMAND = "cpldupdate --dev {} {}" - CPLD_INSTALL_SUCCESS_FLAG = "PASS!" + COMPONENT_NAME = 'CPLD' + COMPONENT_DESCRIPTION = "CPLD - includes all CPLDs in the switch" + COMPONENT_FIRMWARE_EXTENSION = '.vme' - MST_DEVICE_PATTERN = "/dev/mst/mt[0-9]*_pciconf0" + CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' + CPLD_PART_NUMBER_FILE = '/var/run/hw-management/system/cpld{}_pn' + CPLD_VERSION_FILE = '/var/run/hw-management/system/cpld{}_version' + CPLD_VERSION_MINOR_FILE = '/var/run/hw-management/system/cpld{}_version_minor' - def __init__(self): - self.name = COMPONENT_CPLD - self.image_ext_name = ".vme" + CPLD_NUMBER_MAX_LENGTH = 1 + CPLD_PART_NUMBER_MAX_LENGTH = 6 + CPLD_VERSION_MAX_LENGTH = 2 + CPLD_VERSION_MINOR_MAX_LENGTH = 2 + CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}' + CPLD_INSTALL_SUCCESS_FLAG = 'PASS!' - def get_description(self): - """ - Retrieves the description of the component - - Returns: - A string containing the description of the component - """ - return "CPLD - includes all CPLDs in the switch" + MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' + def __init__(self): + self.name = self.COMPONENT_NAME + self.description = self.COMPONENT_DESCRIPTION + self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION def get_firmware_version(self): """ @@ -246,17 +261,34 @@ def get_firmware_version(self): Returns: A string containing the firmware version of the component """ - cpld_version_file_list = glob(self.CPLD_VERSION_FILE_PATTERN) - cpld_version = '' - if cpld_version_file_list: - cpld_version_file_list.sort() - for version_file in cpld_version_file_list: - version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) - if cpld_version: - cpld_version += '.' - cpld_version += version.rstrip('\n') - else: - raise RuntimeError("Failed to get CPLD version files by matching {}".format(self.CPLD_VERSION_FILE_PATTERN)) + cpld_version = EMPTY + + cpld_number = self._read_generic_file(self.CPLD_NUMBER_FILE, self.CPLD_NUMBER_MAX_LENGTH, False) + cpld_number = cpld_number.rstrip(NEWLINE) + + for cpld_idx in xrange(1, int(cpld_number) + 1): + part_number_file = self.CPLD_PART_NUMBER_FILE.format(cpld_idx) + version_file = self.CPLD_VERSION_FILE.format(cpld_idx) + version_minor_file = self.CPLD_VERSION_MINOR_FILE.format(cpld_idx) + + part_number = self._read_generic_file(part_number_file, self.CPLD_PART_NUMBER_MAX_LENGTH) + version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH, False) + version_minor = self._read_generic_file(version_minor_file, self.CPLD_VERSION_MINOR_MAX_LENGTH) + + if part_number is None: + part_number = ZERO + + if version_minor is None: + version_minor = ZERO + + part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) + version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH) + version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) + + if cpld_version: + cpld_version += COMMA + + cpld_version += "CPLD{}:CPLD{}_REV{}{}".format(cpld_idx, part_number, version, version_minor) return cpld_version @@ -331,7 +363,7 @@ def install_firmware(self, image_path): raise RuntimeError("Failed to execute command {} due to {}".format(cmdline, repr(e))) if success_flag: - print("INFO: Success. Refresh or power cycle is required to finish CPLD installation.") + print("INFO: Refresh or power cycle is required to finish CPLD installation") else: print("ERROR: Failed to install CPLD") From ab442fc91bbd0cbeef1f3ef2ba6cd9f939b453ea Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Tue, 3 Mar 2020 09:36:02 +0000 Subject: [PATCH 2/4] [mellanox]: Platform API: code cleanup. Signed-off-by: Nazarii Hnydyn --- .../mellanox/mlnx-platform-api/sonic_platform/component.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index 705513299bef..fcdb7d5df69f 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -23,10 +23,6 @@ COMMA = ',' NEWLINE = '\n' -#components definitions -COMPONENT_BIOS = "BIOS" -COMPONENT_CPLD = "CPLD" - class Component(ComponentBase): def __init__(self): self.name = None From ed015695510b299024f58f6e5fa154aef3905715 Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Wed, 4 Mar 2020 15:59:20 +0000 Subject: [PATCH 3/4] [mellanox]: Align platform API: introduce separate CPLD component representation. Signed-off-by: Nazarii Hnydyn --- .../sonic_platform/chassis.py | 2 +- .../sonic_platform/component.py | 81 ++++++++++--------- 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py index fe8b31898387..00096eecc88c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/chassis.py @@ -154,7 +154,7 @@ def initialize_components(self): # Initialize component list from sonic_platform.component import ComponentBIOS, ComponentCPLD self._component_list.append(ComponentBIOS()) - self._component_list.append(ComponentCPLD()) + self._component_list.extend(ComponentCPLD.get_component_list()) def get_name(self): diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index fcdb7d5df69f..c0db36a9bb46 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -50,7 +50,8 @@ def get_description(self): return self.description - def _read_generic_file(self, filename, len, ignore_errors=True): + @staticmethod + def _read_generic_file(filename, len, ignore_errors=False): """ Read a generic file, returns the contents of the file """ @@ -66,7 +67,8 @@ def _read_generic_file(self, filename, len, ignore_errors=True): return result - def _get_command_result(self, cmdline): + @staticmethod + def _get_command_result(cmdline): try: proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT) stdout = proc.communicate()[0] @@ -107,17 +109,17 @@ class ComponentBIOS(Component): ONIE_VERSION_MAJOR_OFFSET = 1 ONIE_VERSION_MINOR_OFFSET = 2 ONIE_VERSION_RELEASE_OFFSET = 3 - ONIE_REQUIRED_MAJOR = "5" - ONIE_REQUIRED_MINOR = "2" - ONIE_REQUIRED_RELEASE = "0016" + ONIE_REQUIRED_MAJOR = '5' + ONIE_REQUIRED_MINOR = '2' + ONIE_REQUIRED_RELEASE = '0016' BIOS_VERSION_PARSE_PATTERN = 'OEM[\s]*Strings\n[\s]*String[\s]*1:[\s]*([0-9a-zA-Z_\.]*)' BIOS_PENDING_UPDATE_PATTERN = '([0-9A-Za-z_]*.rom)[\s]*\|[\s]*bios_update' - ONIE_FW_UPDATE_CMD_ADD = "/usr/bin/onie-fw-update.sh add {}" - ONIE_FW_UPDATE_CMD_REMOVE = "/usr/bin/onie-fw-update.sh remove {}" - ONIE_FW_UPDATE_CMD_UPDATE = "/usr/bin/onie-fw-update.sh update" - ONIE_FW_UPDATE_CMD_SHOW = "/usr/bin/onie-fw-update.sh show-pending" + ONIE_FW_UPDATE_CMD_ADD = '/usr/bin/onie-fw-update.sh add {}' + ONIE_FW_UPDATE_CMD_REMOVE = '/usr/bin/onie-fw-update.sh remove {}' + ONIE_FW_UPDATE_CMD_UPDATE = '/usr/bin/onie-fw-update.sh update' + ONIE_FW_UPDATE_CMD_SHOW = '/usr/bin/onie-fw-update.sh show-pending' BIOS_QUERY_VERSION_COMMAND = 'dmidecode -t 11' @@ -226,8 +228,8 @@ def install_firmware(self, image_path): class ComponentCPLD(Component): - COMPONENT_NAME = 'CPLD' - COMPONENT_DESCRIPTION = "CPLD - includes all CPLDs in the switch" + COMPONENT_NAME = 'CPLD{}' + COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device' COMPONENT_FIRMWARE_EXTENSION = '.vme' CPLD_NUMBER_FILE = '/var/run/hw-management/config/cpld_num' @@ -245,11 +247,13 @@ class ComponentCPLD(Component): MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0' - def __init__(self): - self.name = self.COMPONENT_NAME + def __init__(self, idx): + self.idx = idx + self.name = self.COMPONENT_NAME.format(self.idx) self.description = self.COMPONENT_DESCRIPTION self.image_ext_name = self.COMPONENT_FIRMWARE_EXTENSION + def get_firmware_version(self): """ Retrieves the firmware version of the component @@ -257,36 +261,26 @@ def get_firmware_version(self): Returns: A string containing the firmware version of the component """ - cpld_version = EMPTY - - cpld_number = self._read_generic_file(self.CPLD_NUMBER_FILE, self.CPLD_NUMBER_MAX_LENGTH, False) - cpld_number = cpld_number.rstrip(NEWLINE) - - for cpld_idx in xrange(1, int(cpld_number) + 1): - part_number_file = self.CPLD_PART_NUMBER_FILE.format(cpld_idx) - version_file = self.CPLD_VERSION_FILE.format(cpld_idx) - version_minor_file = self.CPLD_VERSION_MINOR_FILE.format(cpld_idx) - - part_number = self._read_generic_file(part_number_file, self.CPLD_PART_NUMBER_MAX_LENGTH) - version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH, False) - version_minor = self._read_generic_file(version_minor_file, self.CPLD_VERSION_MINOR_MAX_LENGTH) - if part_number is None: - part_number = ZERO + part_number_file = self.CPLD_PART_NUMBER_FILE.format(self.idx) + version_file = self.CPLD_VERSION_FILE.format(self.idx) + version_minor_file = self.CPLD_VERSION_MINOR_FILE.format(self.idx) - if version_minor is None: - version_minor = ZERO + part_number = self._read_generic_file(part_number_file, self.CPLD_PART_NUMBER_MAX_LENGTH, True) + version = self._read_generic_file(version_file, self.CPLD_VERSION_MAX_LENGTH) + version_minor = self._read_generic_file(version_minor_file, self.CPLD_VERSION_MINOR_MAX_LENGTH, True) - part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) - version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH) - version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) + if part_number is None: + part_number = ZERO - if cpld_version: - cpld_version += COMMA + if version_minor is None: + version_minor = ZERO - cpld_version += "CPLD{}:CPLD{}_REV{}{}".format(cpld_idx, part_number, version, version_minor) + part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) + version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH) + version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH) - return cpld_version + return "CPLD{}_REV{}{}".format(part_number, version, version_minor) def _get_mst_device(self): @@ -364,3 +358,16 @@ def install_firmware(self, image_path): print("ERROR: Failed to install CPLD") return success_flag + + + @classmethod + def get_component_list(cls): + component_list = [ ] + + cpld_number = cls._read_generic_file(cls.CPLD_NUMBER_FILE, cls.CPLD_NUMBER_MAX_LENGTH) + cpld_number = cpld_number.rstrip(NEWLINE) + + for cpld_idx in xrange(1, int(cpld_number) + 1): + component_list.append(cls(cpld_idx)) + + return component_list From 4a633b1b9e87926eaef7cfeb80ad15ff5b21d06f Mon Sep 17 00:00:00 2001 From: Nazarii Hnydyn Date: Thu, 12 Mar 2020 07:38:54 +0000 Subject: [PATCH 4/4] [mellanox]: Align platform API: fix review comments. Signed-off-by: Nazarii Hnydyn --- .../mlnx-platform-api/sonic_platform/component.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py index c0db36a9bb46..70fd96023b8c 100644 --- a/platform/mellanox/mlnx-platform-api/sonic_platform/component.py +++ b/platform/mellanox/mlnx-platform-api/sonic_platform/component.py @@ -18,9 +18,7 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -EMPTY = '' ZERO = '0' -COMMA = ',' NEWLINE = '\n' class Component(ComponentBase): @@ -242,6 +240,9 @@ class ComponentCPLD(Component): CPLD_VERSION_MAX_LENGTH = 2 CPLD_VERSION_MINOR_MAX_LENGTH = 2 + CPLD_PART_NUMBER_DEFAULT = ZERO + CPLD_VERSION_MINOR_DEFAULT = ZERO + CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}' CPLD_INSTALL_SUCCESS_FLAG = 'PASS!' @@ -271,10 +272,10 @@ def get_firmware_version(self): version_minor = self._read_generic_file(version_minor_file, self.CPLD_VERSION_MINOR_MAX_LENGTH, True) if part_number is None: - part_number = ZERO + part_number = self.CPLD_PART_NUMBER_DEFAULT if version_minor is None: - version_minor = ZERO + version_minor = self.CPLD_VERSION_MINOR_DEFAULT part_number = part_number.rstrip(NEWLINE).zfill(self.CPLD_PART_NUMBER_MAX_LENGTH) version = version.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MAX_LENGTH)