Skip to content

Commit

Permalink
[mellanox]: Align platform API: change CPLD version representation (s…
Browse files Browse the repository at this point in the history
  • Loading branch information
nazariig authored and tiantianlv committed Apr 24, 2020
1 parent f3de96d commit 2a315b6
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,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):
Expand Down
148 changes: 92 additions & 56 deletions platform/mellanox/mlnx-platform-api/sonic_platform/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

#components definitions
COMPONENT_BIOS = "BIOS"
COMPONENT_CPLD = "CPLD"
ZERO = '0'
NEWLINE = '\n'

class Component(ComponentBase):
def __init__(self):
self.name = None
self.description = None
self.image_ext_name = None


Expand All @@ -38,20 +38,35 @@ 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


@staticmethod
def _read_generic_file(filename, len, ignore_errors=False):
"""
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):
@staticmethod
def _get_command_result(cmdline):
try:
proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE, shell=True, stderr=subprocess.STDOUT)
stdout = proc.communicate()[0]
Expand Down Expand Up @@ -83,38 +98,33 @@ 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
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'

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):
Expand Down Expand Up @@ -210,33 +220,39 @@ 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
COMPONENT_NAME = 'CPLD{}'
COMPONENT_DESCRIPTION = 'CPLD - Complex Programmable Logic Device'
COMPONENT_FIRMWARE_EXTENSION = '.vme'

CPLD_UPDATE_COMMAND = "cpldupdate --dev {} {}"
CPLD_INSTALL_SUCCESS_FLAG = "PASS!"
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'

MST_DEVICE_PATTERN = "/dev/mst/mt[0-9]*_pciconf0"
CPLD_NUMBER_MAX_LENGTH = 1
CPLD_PART_NUMBER_MAX_LENGTH = 6
CPLD_VERSION_MAX_LENGTH = 2
CPLD_VERSION_MINOR_MAX_LENGTH = 2

def __init__(self):
self.name = COMPONENT_CPLD
self.image_ext_name = ".vme"
CPLD_PART_NUMBER_DEFAULT = ZERO
CPLD_VERSION_MINOR_DEFAULT = ZERO

CPLD_UPDATE_COMMAND = 'cpldupdate --dev {} {}'
CPLD_INSTALL_SUCCESS_FLAG = 'PASS!'

def get_description(self):
"""
Retrieves the description of the component
MST_DEVICE_PATTERN = '/dev/mst/mt[0-9]*_pci_cr0'

Returns:
A string containing the description of the component
"""
return "CPLD - includes all CPLDs in the switch"
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):
Expand All @@ -246,19 +262,26 @@ 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))

return cpld_version
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)

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)

if part_number is None:
part_number = self.CPLD_PART_NUMBER_DEFAULT

if version_minor is None:
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)
version_minor = version_minor.rstrip(NEWLINE).zfill(self.CPLD_VERSION_MINOR_MAX_LENGTH)

return "CPLD{}_REV{}{}".format(part_number, version, version_minor)


def _get_mst_device(self):
Expand Down Expand Up @@ -331,8 +354,21 @@ 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")

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

0 comments on commit 2a315b6

Please sign in to comment.