DellEMC : Platform2.0 API Implementation for Component [S6000, S6100, Z9100] (#3588)
This commit is contained in:
parent
2d87ca4a18
commit
ee4ca2c0c5
@ -18,6 +18,7 @@ try:
|
|||||||
from sonic_platform.fan import Fan
|
from sonic_platform.fan import Fan
|
||||||
from sonic_platform.psu import Psu
|
from sonic_platform.psu import Psu
|
||||||
from sonic_platform.thermal import Thermal
|
from sonic_platform.thermal import Thermal
|
||||||
|
from sonic_platform.component import Component
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
@ -25,17 +26,7 @@ except ImportError as e:
|
|||||||
MAX_S6000_FAN = 3
|
MAX_S6000_FAN = 3
|
||||||
MAX_S6000_PSU = 2
|
MAX_S6000_PSU = 2
|
||||||
MAX_S6000_THERMAL = 10
|
MAX_S6000_THERMAL = 10
|
||||||
|
MAX_S6000_COMPONENT = 4
|
||||||
BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version"
|
|
||||||
#components definitions
|
|
||||||
COMPONENT_BIOS = "BIOS"
|
|
||||||
COMPONENT_CPLD1 = "CPLD1"
|
|
||||||
COMPONENT_CPLD2 = "CPLD2"
|
|
||||||
COMPONENT_CPLD3 = "CPLD3"
|
|
||||||
|
|
||||||
CPLD1_VERSION = 'system_cpld_ver'
|
|
||||||
CPLD2_VERSION = 'master_cpld_ver'
|
|
||||||
CPLD3_VERSION = 'slave_cpld_ver'
|
|
||||||
|
|
||||||
|
|
||||||
class Chassis(ChassisBase):
|
class Chassis(ChassisBase):
|
||||||
@ -87,11 +78,9 @@ class Chassis(ChassisBase):
|
|||||||
thermal = Thermal(i)
|
thermal = Thermal(i)
|
||||||
self._thermal_list.append(thermal)
|
self._thermal_list.append(thermal)
|
||||||
|
|
||||||
# Initialize component list
|
for i in range(MAX_S6000_COMPONENT):
|
||||||
self._component_name_list.append(COMPONENT_BIOS)
|
component = Component(i)
|
||||||
self._component_name_list.append(COMPONENT_CPLD1)
|
self._component_list.append(component)
|
||||||
self._component_name_list.append(COMPONENT_CPLD2)
|
|
||||||
self._component_name_list.append(COMPONENT_CPLD3)
|
|
||||||
|
|
||||||
def _get_cpld_register(self, reg_name):
|
def _get_cpld_register(self, reg_name):
|
||||||
rv = 'ERR'
|
rv = 'ERR'
|
||||||
@ -178,7 +167,7 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A dictionary where keys are the type code defined in
|
A dictionary where keys are the type code defined in
|
||||||
OCP ONIE TlvInfo EEPROM format and values are their
|
OCP ONIE TlvInfo EEPROM format and values are their
|
||||||
corresponding values.
|
corresponding values.
|
||||||
"""
|
"""
|
||||||
return self.sys_eeprom.system_eeprom_info()
|
return self.sys_eeprom.system_eeprom_info()
|
||||||
@ -200,46 +189,6 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
|
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||||
|
|
||||||
def _get_command_result(self, cmdline):
|
|
||||||
try:
|
|
||||||
proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
|
||||||
shell=True, stderr=subprocess.STDOUT)
|
|
||||||
stdout = proc.communicate()[0]
|
|
||||||
proc.wait()
|
|
||||||
result = stdout.rstrip('\n')
|
|
||||||
except OSError:
|
|
||||||
result = ''
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _get_cpld_version(self,cpld_name):
|
|
||||||
"""
|
|
||||||
Cpld Version
|
|
||||||
"""
|
|
||||||
cpld_ver = int(self._get_cpld_register(cpld_name),16)
|
|
||||||
return cpld_ver
|
|
||||||
|
|
||||||
def get_firmware_version(self, component_name):
|
|
||||||
"""
|
|
||||||
Retrieves platform-specific hardware/firmware versions for
|
|
||||||
chassis componenets such as BIOS, CPLD, FPGA, etc.
|
|
||||||
Args:
|
|
||||||
component_name: A string, the component name.
|
|
||||||
Returns:
|
|
||||||
A string containing platform-specific component versions
|
|
||||||
"""
|
|
||||||
if component_name in self._component_name_list :
|
|
||||||
if component_name == COMPONENT_BIOS:
|
|
||||||
return self._get_command_result(BIOS_QUERY_VERSION_COMMAND)
|
|
||||||
elif component_name == COMPONENT_CPLD1:
|
|
||||||
return self._get_cpld_version(CPLD1_VERSION)
|
|
||||||
elif component_name == COMPONENT_CPLD2:
|
|
||||||
return self._get_cpld_version(CPLD2_VERSION)
|
|
||||||
elif component_name == COMPONENT_CPLD3:
|
|
||||||
return self._get_cpld_version(CPLD3_VERSION)
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _get_transceiver_status(self):
|
def _get_transceiver_status(self):
|
||||||
presence_ctrl = self.sfp_control + 'qsfp_modprs'
|
presence_ctrl = self.sfp_control + 'qsfp_modprs'
|
||||||
try:
|
try:
|
||||||
|
@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# DELLEMC S6000
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in
|
||||||
|
# the platform
|
||||||
|
#
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from sonic_platform_base.component_base import ComponentBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version"
|
||||||
|
|
||||||
|
|
||||||
|
class Component(ComponentBase):
|
||||||
|
"""DellEMC Platform-specific Component class"""
|
||||||
|
|
||||||
|
CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0"
|
||||||
|
|
||||||
|
CHASSIS_COMPONENTS = [
|
||||||
|
["BIOS", ("Performs initialization of hardware components during "
|
||||||
|
"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)"]
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, component_index):
|
||||||
|
self.index = component_index
|
||||||
|
self.name = self.CHASSIS_COMPONENTS[self.index][0]
|
||||||
|
self.description = self.CHASSIS_COMPONENTS[self.index][1]
|
||||||
|
|
||||||
|
def _get_cpld_register(self, reg_name):
|
||||||
|
rv = 'ERR'
|
||||||
|
mb_reg_file = self.CPLD_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_command_result(self, cmdline):
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
stdout = proc.communicate()[0]
|
||||||
|
proc.wait()
|
||||||
|
result = stdout.rstrip('\n')
|
||||||
|
except OSError:
|
||||||
|
result = None
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _get_cpld_version(self, cpld_number):
|
||||||
|
cpld_version_reg = {
|
||||||
|
1: "system_cpld_ver",
|
||||||
|
2: "master_cpld_ver",
|
||||||
|
3: "slave_cpld_ver"
|
||||||
|
}
|
||||||
|
|
||||||
|
cpld_version = self._get_cpld_register(cpld_version_reg[cpld_number])
|
||||||
|
|
||||||
|
if cpld_version != 'ERR':
|
||||||
|
return str(int(cpld_version, 16))
|
||||||
|
else:
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the name of the component
|
||||||
|
"""
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def get_description(self):
|
||||||
|
"""
|
||||||
|
Retrieves the description of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the description of the component
|
||||||
|
"""
|
||||||
|
return self.description
|
||||||
|
|
||||||
|
def get_firmware_version(self):
|
||||||
|
"""
|
||||||
|
Retrieves the firmware version of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the firmware version of the component
|
||||||
|
"""
|
||||||
|
if self.index == 0:
|
||||||
|
bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND)
|
||||||
|
|
||||||
|
if not bios_ver:
|
||||||
|
return 'NA'
|
||||||
|
else:
|
||||||
|
return bios_ver
|
||||||
|
|
||||||
|
elif self.index <= 3:
|
||||||
|
return self._get_cpld_version(self.index)
|
||||||
|
|
||||||
|
def install_firmware(self, image_path):
|
||||||
|
"""
|
||||||
|
Installs firmware to the component
|
||||||
|
|
||||||
|
Args:
|
||||||
|
image_path: A string, path to firmware image
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if install was successful, False if not
|
||||||
|
"""
|
||||||
|
return False
|
@ -10,11 +10,6 @@
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import click
|
|
||||||
import subprocess
|
|
||||||
import glob
|
|
||||||
import sonic_device_util
|
|
||||||
from sonic_platform_base.platform_base import PlatformBase
|
from sonic_platform_base.platform_base import PlatformBase
|
||||||
from sonic_platform_base.chassis_base import ChassisBase
|
from sonic_platform_base.chassis_base import ChassisBase
|
||||||
from sonic_platform.sfp import Sfp
|
from sonic_platform.sfp import Sfp
|
||||||
@ -22,6 +17,7 @@ try:
|
|||||||
from sonic_platform.fan import Fan
|
from sonic_platform.fan import Fan
|
||||||
from sonic_platform.module import Module
|
from sonic_platform.module import Module
|
||||||
from sonic_platform.thermal import Thermal
|
from sonic_platform.thermal import Thermal
|
||||||
|
from sonic_platform.component import Component
|
||||||
from eeprom import Eeprom
|
from eeprom import Eeprom
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
@ -30,12 +26,7 @@ MAX_S6100_MODULE = 4
|
|||||||
MAX_S6100_FAN = 4
|
MAX_S6100_FAN = 4
|
||||||
MAX_S6100_PSU = 2
|
MAX_S6100_PSU = 2
|
||||||
MAX_S6100_THERMAL = 10
|
MAX_S6100_THERMAL = 10
|
||||||
|
MAX_S6100_COMPONENT = 3
|
||||||
BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version"
|
|
||||||
#components definitions
|
|
||||||
COMPONENT_BIOS = "BIOS"
|
|
||||||
SWITCH_CPLD = "CPLD"
|
|
||||||
SMF_FPGA = "FPGA1"
|
|
||||||
|
|
||||||
|
|
||||||
class Chassis(ChassisBase):
|
class Chassis(ChassisBase):
|
||||||
@ -80,10 +71,9 @@ class Chassis(ChassisBase):
|
|||||||
thermal = Thermal(i)
|
thermal = Thermal(i)
|
||||||
self._thermal_list.append(thermal)
|
self._thermal_list.append(thermal)
|
||||||
|
|
||||||
# Initialize component list
|
for i in range(MAX_S6100_COMPONENT):
|
||||||
self._component_name_list.append(COMPONENT_BIOS)
|
component = Component(i)
|
||||||
self._component_name_list.append(SWITCH_CPLD)
|
self._component_list.append(component)
|
||||||
self._component_name_list.append(SMF_FPGA)
|
|
||||||
|
|
||||||
def _get_reboot_reason_smf_register(self):
|
def _get_reboot_reason_smf_register(self):
|
||||||
# Returns 0xAA on software reload
|
# Returns 0xAA on software reload
|
||||||
@ -111,19 +101,6 @@ class Chassis(ChassisBase):
|
|||||||
rv = rv.lstrip(" ")
|
rv = rv.lstrip(" ")
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
# Run bash command and print output to stdout
|
|
||||||
def run_command(self, command):
|
|
||||||
click.echo(click.style("Command: ", fg='cyan') +
|
|
||||||
click.style(command, fg='green'))
|
|
||||||
|
|
||||||
proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
|
|
||||||
(out, err) = proc.communicate()
|
|
||||||
|
|
||||||
click.echo(out)
|
|
||||||
|
|
||||||
if proc.returncode != 0:
|
|
||||||
sys.exit(proc.returncode)
|
|
||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the chassis
|
Retrieves the name of the chassis
|
||||||
@ -234,147 +211,3 @@ class Chassis(ChassisBase):
|
|||||||
return (self.reset_reason_dict[reset_reason], None)
|
return (self.reset_reason_dict[reset_reason], None)
|
||||||
|
|
||||||
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
||||||
|
|
||||||
def _get_command_result(self, cmdline):
|
|
||||||
try:
|
|
||||||
proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
|
||||||
shell=True, stderr=subprocess.STDOUT)
|
|
||||||
stdout = proc.communicate()[0]
|
|
||||||
proc.wait()
|
|
||||||
result = stdout.rstrip('\n')
|
|
||||||
except OSError:
|
|
||||||
result = ''
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _get_cpld_version(self):
|
|
||||||
io_resource = "/dev/port"
|
|
||||||
CPLD1_VERSION_ADDR = 0x100
|
|
||||||
|
|
||||||
fd = os.open(io_resource, os.O_RDONLY)
|
|
||||||
if (fd < 0):
|
|
||||||
return 'NA'
|
|
||||||
if (os.lseek(fd, CPLD1_VERSION_ADDR, os.SEEK_SET)
|
|
||||||
!= CPLD1_VERSION_ADDR):
|
|
||||||
return 'NA'
|
|
||||||
|
|
||||||
buf = os.read(fd, 1)
|
|
||||||
cpld_version = ord(buf)
|
|
||||||
os.close(fd)
|
|
||||||
|
|
||||||
return "%d.%d" % (((cpld_version & 0xF0) >> 4), cpld_version & 0xF)
|
|
||||||
|
|
||||||
def _get_fpga_version(self):
|
|
||||||
fpga_ver = float(self._get_pmc_register('smf_firmware_ver'))
|
|
||||||
return fpga_ver
|
|
||||||
|
|
||||||
def get_firmware_version(self, component_name):
|
|
||||||
"""
|
|
||||||
Retrieves platform-specific hardware/firmware versions for
|
|
||||||
chassis componenets such as BIOS, CPLD, FPGA, etc.
|
|
||||||
Args:
|
|
||||||
component_name: A string, the component name.
|
|
||||||
Returns:
|
|
||||||
A string containing platform-specific component versions
|
|
||||||
"""
|
|
||||||
if component_name in self._component_name_list :
|
|
||||||
if component_name == COMPONENT_BIOS:
|
|
||||||
return self._get_command_result(BIOS_QUERY_VERSION_COMMAND)
|
|
||||||
elif component_name == SWITCH_CPLD:
|
|
||||||
return self._get_cpld_version()
|
|
||||||
elif component_name == SMF_FPGA:
|
|
||||||
return self._get_fpga_version()
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
|
||||||
def install_component_firmware(self, component_name, image_path):
|
|
||||||
|
|
||||||
bios_image = None
|
|
||||||
bios_version = "3.25.0."
|
|
||||||
bios_file_name = "S6100*BIOS*"
|
|
||||||
flashrom = "/usr/local/bin/flashrom"
|
|
||||||
PLATFORM_ROOT_PATH = '/usr/share/sonic/device'
|
|
||||||
machine_info = sonic_device_util.get_machine_info()
|
|
||||||
platform = sonic_device_util.get_platform_info(machine_info)
|
|
||||||
platform_path = "/".join([PLATFORM_ROOT_PATH, platform, "bin"])
|
|
||||||
|
|
||||||
warning = """
|
|
||||||
********************************************************************
|
|
||||||
* Warning - Upgrading BIOS is inherently risky and should only be *
|
|
||||||
* attempted when necessary. A failure at this upgrade may cause *
|
|
||||||
* a board RMA. Proceed with caution ! *
|
|
||||||
********************************************************************
|
|
||||||
"""
|
|
||||||
|
|
||||||
if component_name in self._component_name_list:
|
|
||||||
if component_name == COMPONENT_BIOS: # BIOS
|
|
||||||
|
|
||||||
# current BIOS version
|
|
||||||
current_bios_version = self.get_firmware_version("BIOS")
|
|
||||||
|
|
||||||
# Construct BIOS image path
|
|
||||||
if image_path is not None:
|
|
||||||
image_path = image_path + platform_path
|
|
||||||
for name in glob.glob(
|
|
||||||
os.path.join(image_path, bios_file_name)):
|
|
||||||
bios_image = image_path = name
|
|
||||||
|
|
||||||
if not bios_image:
|
|
||||||
print "BIOS image file not found:", image_path
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Extract BIOS image version
|
|
||||||
bios_image = os.path.basename(bios_image)
|
|
||||||
bios_image = bios_image.strip('S6100-BIOS-')
|
|
||||||
bios_image_version = bios_image.strip('.bin')
|
|
||||||
|
|
||||||
if bios_image_version.startswith(bios_version):
|
|
||||||
bios_image_minor = bios_image_version.replace(
|
|
||||||
bios_image_version[:7], '')
|
|
||||||
if bios_image_minor.startswith("2"):
|
|
||||||
bios_image_minor = bios_image_minor.split("-")[1]
|
|
||||||
|
|
||||||
if current_bios_version.startswith(bios_version):
|
|
||||||
current_bios_minor = current_bios_version.replace(
|
|
||||||
current_bios_version[:7], '')
|
|
||||||
if current_bios_minor.startswith("2"):
|
|
||||||
current_bios_minor = current_bios_minor.split("-")[1]
|
|
||||||
|
|
||||||
# BIOS version check
|
|
||||||
if bios_image_minor > current_bios_minor:
|
|
||||||
|
|
||||||
print warning
|
|
||||||
prompt_text = "New BIOS image " + bios_image_version + \
|
|
||||||
" available to install, continue?"
|
|
||||||
yes = click.confirm(prompt_text)
|
|
||||||
|
|
||||||
elif current_bios_minor > bios_image_minor:
|
|
||||||
|
|
||||||
print warning
|
|
||||||
prompt_text = "Do you want to downgrade BIOS image from " \
|
|
||||||
+ current_bios_version + " to " + \
|
|
||||||
bios_image_version + " continue?"
|
|
||||||
|
|
||||||
yes = click.confirm(prompt_text)
|
|
||||||
|
|
||||||
else:
|
|
||||||
print("BIOS is already with {} latest version".format(
|
|
||||||
current_bios_version))
|
|
||||||
return True
|
|
||||||
|
|
||||||
if yes:
|
|
||||||
command = flashrom + " -p" + " internal" + " -w " + \
|
|
||||||
image_path
|
|
||||||
self.run_command(command)
|
|
||||||
|
|
||||||
elif component_name == SWITCH_CPLD: # CPLD
|
|
||||||
return False
|
|
||||||
|
|
||||||
elif component_name == SMF_FPGA: # SMF
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
print "Invalid component Name:", component_name
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,177 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# DELLEMC S6100
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in
|
||||||
|
# the platform
|
||||||
|
#
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from sonic_platform_base.component_base import ComponentBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version"
|
||||||
|
|
||||||
|
|
||||||
|
class Component(ComponentBase):
|
||||||
|
"""DellEMC Platform-specific Component class"""
|
||||||
|
|
||||||
|
HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/"
|
||||||
|
HWMON_NODE = os.listdir(HWMON_DIR)[0]
|
||||||
|
MAILBOX_DIR = HWMON_DIR + HWMON_NODE
|
||||||
|
|
||||||
|
CHASSIS_COMPONENTS = [
|
||||||
|
["BIOS", ("Performs initialization of hardware components during "
|
||||||
|
"booting")],
|
||||||
|
["CPLD", "Used for managing IO modules, SFP+ modules and system LEDs"],
|
||||||
|
["FPGA", ("Platform management controller for on-board temperature "
|
||||||
|
"monitoring, in-chassis power, Fan and LED control")]
|
||||||
|
]
|
||||||
|
MODULE_COMPONENT = [
|
||||||
|
"IOM{}-CPLD",
|
||||||
|
"Used for managing QSFP+ modules ({0}-{1})"
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, component_index=0,
|
||||||
|
is_module=False, iom_index=0, i2c_line=0):
|
||||||
|
|
||||||
|
self.is_module_component = is_module
|
||||||
|
|
||||||
|
if self.is_module_component:
|
||||||
|
self.index = iom_index
|
||||||
|
self.name = self.MODULE_COMPONENT[0].format(self.index)
|
||||||
|
self.description = self.MODULE_COMPONENT[1].format(
|
||||||
|
((self.index - 1) * 16) + 1, self.index * 16)
|
||||||
|
self.cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e"
|
||||||
|
"/iom_cpld_vers").format(i2c_line)
|
||||||
|
else:
|
||||||
|
self.index = component_index
|
||||||
|
self.name = self.CHASSIS_COMPONENTS[self.index][0]
|
||||||
|
self.description = self.CHASSIS_COMPONENTS[self.index][1]
|
||||||
|
|
||||||
|
def _read_sysfs_file(self, sysfs_file):
|
||||||
|
# On successful read, returns the value read from given
|
||||||
|
# sysfs_file and on failure returns 'ERR'
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
if (not os.path.isfile(sysfs_file)):
|
||||||
|
return rv
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(sysfs_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_command_result(self, cmdline):
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
stdout = proc.communicate()[0]
|
||||||
|
proc.wait()
|
||||||
|
result = stdout.rstrip('\n')
|
||||||
|
except OSError:
|
||||||
|
result = None
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _get_cpld_version(self):
|
||||||
|
io_resource = "/dev/port"
|
||||||
|
CPLD_VERSION_ADDR = 0x100
|
||||||
|
|
||||||
|
fd = os.open(io_resource, os.O_RDONLY)
|
||||||
|
if (fd < 0):
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
if (os.lseek(fd, CPLD_VERSION_ADDR, os.SEEK_SET) != CPLD_VERSION_ADDR):
|
||||||
|
os.close(fd)
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
buf = os.read(fd, 1)
|
||||||
|
cpld_version = str(ord(buf))
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
return cpld_version
|
||||||
|
|
||||||
|
def _get_iom_cpld_version(self):
|
||||||
|
ver_str = self._read_sysfs_file(self.cpld_version_file)
|
||||||
|
if (ver_str != 'ERR'):
|
||||||
|
if ver_str == 'read error':
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
ver_str = ver_str.rstrip('\r\n')
|
||||||
|
cpld_version = str(int(ver_str.split(':')[1], 16))
|
||||||
|
return cpld_version
|
||||||
|
else:
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
def _get_fpga_version(self):
|
||||||
|
fpga_ver_file = self.MAILBOX_DIR + '/smf_firmware_ver'
|
||||||
|
fpga_ver = self._read_sysfs_file(fpga_ver_file)
|
||||||
|
if (fpga_ver != 'ERR'):
|
||||||
|
return fpga_ver
|
||||||
|
else:
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the name of the component
|
||||||
|
"""
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def get_description(self):
|
||||||
|
"""
|
||||||
|
Retrieves the description of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the description of the component
|
||||||
|
"""
|
||||||
|
return self.description
|
||||||
|
|
||||||
|
def get_firmware_version(self):
|
||||||
|
"""
|
||||||
|
Retrieves the firmware version of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the firmware version of the component
|
||||||
|
"""
|
||||||
|
if self.is_module_component: # IOM CPLD
|
||||||
|
return self._get_iom_cpld_version()
|
||||||
|
else:
|
||||||
|
if self.index == 0: # BIOS
|
||||||
|
bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND)
|
||||||
|
|
||||||
|
if not bios_ver:
|
||||||
|
return 'NA'
|
||||||
|
else:
|
||||||
|
return bios_ver
|
||||||
|
|
||||||
|
elif self.index == 1: # SwitchCard CPLD
|
||||||
|
return self._get_cpld_version()
|
||||||
|
elif self.index == 2: # FPGA
|
||||||
|
return self._get_fpga_version()
|
||||||
|
|
||||||
|
def install_firmware(self, image_path):
|
||||||
|
"""
|
||||||
|
Installs firmware to the component
|
||||||
|
|
||||||
|
Args:
|
||||||
|
image_path: A string, path to firmware image
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if install was successful, False if not
|
||||||
|
"""
|
||||||
|
return False
|
@ -13,6 +13,7 @@ try:
|
|||||||
import os
|
import os
|
||||||
from sonic_platform_base.module_base import ModuleBase
|
from sonic_platform_base.module_base import ModuleBase
|
||||||
from sonic_platform.sfp import Sfp
|
from sonic_platform.sfp import Sfp
|
||||||
|
from sonic_platform.component import Component
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
@ -54,16 +55,20 @@ class Module(ModuleBase):
|
|||||||
self.port_start = (self.index - 1) * 16
|
self.port_start = (self.index - 1) * 16
|
||||||
self.port_end = (self.index * 16) - 1
|
self.port_end = (self.index * 16) - 1
|
||||||
self.port_i2c_line = self.IOM_I2C_MAPPING[self.index]
|
self.port_i2c_line = self.IOM_I2C_MAPPING[self.index]
|
||||||
self._component_name_list = ['CPLD']
|
|
||||||
self.eeprom_tlv_dict = dict()
|
self.eeprom_tlv_dict = dict()
|
||||||
|
|
||||||
self.iom_status_reg = "iom_status"
|
self.iom_status_reg = "iom_status"
|
||||||
self.iom_presence_reg = "iom_presence"
|
self.iom_presence_reg = "iom_presence"
|
||||||
|
|
||||||
# Overriding _sfp_list class variable defined in ModuleBase, to
|
# Overriding _component_list and _sfp_list class variables defined in
|
||||||
# make it unique per Module object
|
# ModuleBase, to make them unique per Module object
|
||||||
|
self._component_list = []
|
||||||
self._sfp_list = []
|
self._sfp_list = []
|
||||||
|
|
||||||
|
component = Component(is_module=True, iom_index=self.index,
|
||||||
|
i2c_line=self.port_i2c_line)
|
||||||
|
self._component_list.append(component)
|
||||||
|
|
||||||
eeprom_base = "/sys/class/i2c-adapter/i2c-{0}/i2c-{1}/{1}-0050/eeprom"
|
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_ctrl_base = "/sys/class/i2c-adapter/i2c-{0}/{0}-003e/"
|
||||||
|
|
||||||
@ -188,39 +193,3 @@ class Module(ModuleBase):
|
|||||||
‘0x26’:’01’, ‘0x27’:’REV01’, ‘0x28’:’AG9064-C2358-16G’}
|
‘0x26’:’01’, ‘0x27’:’REV01’, ‘0x28’:’AG9064-C2358-16G’}
|
||||||
"""
|
"""
|
||||||
return self.eeprom_tlv_dict
|
return self.eeprom_tlv_dict
|
||||||
|
|
||||||
def get_firmware_version(self, component_name):
|
|
||||||
"""
|
|
||||||
Retrieves platform-specific hardware/firmware versions for module
|
|
||||||
componenets such as BIOS, CPLD, FPGA, etc.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
component_name: A string, the component name.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A string containing platform-specific component versions
|
|
||||||
"""
|
|
||||||
if component_name == 'CPLD':
|
|
||||||
cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e/"
|
|
||||||
"iom_cpld_vers").format(self.port_i2c_line)
|
|
||||||
|
|
||||||
if (not os.path.isfile(cpld_version_file)):
|
|
||||||
return 'NA'
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(cpld_version_file, 'r') as fd:
|
|
||||||
ver_str = fd.read()
|
|
||||||
except Exception as error:
|
|
||||||
return 'NA'
|
|
||||||
|
|
||||||
if ver_str == 'read error':
|
|
||||||
return 'NA'
|
|
||||||
|
|
||||||
ver_str = ver_str.rstrip('\r\n')
|
|
||||||
cpld_version = int(ver_str.split(':')[1], 16)
|
|
||||||
major_version = (cpld_version & 0xF0) >> 4
|
|
||||||
minor_version = cpld_version & 0xF
|
|
||||||
|
|
||||||
return "%d.%d" % (major_version, minor_version)
|
|
||||||
else:
|
|
||||||
return 'NA'
|
|
||||||
|
@ -17,6 +17,7 @@ try:
|
|||||||
from sonic_platform.fan import Fan
|
from sonic_platform.fan import Fan
|
||||||
from sonic_platform.psu import Psu
|
from sonic_platform.psu import Psu
|
||||||
from sonic_platform.thermal import Thermal
|
from sonic_platform.thermal import Thermal
|
||||||
|
from sonic_platform.component import Component
|
||||||
from eeprom import Eeprom
|
from eeprom import Eeprom
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
@ -26,15 +27,7 @@ MAX_Z9100_FANTRAY = 5
|
|||||||
MAX_Z9100_FAN = 2
|
MAX_Z9100_FAN = 2
|
||||||
MAX_Z9100_PSU = 2
|
MAX_Z9100_PSU = 2
|
||||||
MAX_Z9100_THERMAL = 8
|
MAX_Z9100_THERMAL = 8
|
||||||
|
MAX_Z9100_COMPONENT = 6
|
||||||
BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version"
|
|
||||||
#components definitions
|
|
||||||
COMPONENT_BIOS = "BIOS"
|
|
||||||
SWITCH_CPLD1 = "CPLD1"
|
|
||||||
SWITCH_CPLD2 = "CPLD2"
|
|
||||||
SWITCH_CPLD3 = "CPLD3"
|
|
||||||
SWITCH_CPLD4 = "CPLD4"
|
|
||||||
SMF_FPGA = "FPGA1"
|
|
||||||
|
|
||||||
|
|
||||||
class Chassis(ChassisBase):
|
class Chassis(ChassisBase):
|
||||||
@ -115,13 +108,9 @@ class Chassis(ChassisBase):
|
|||||||
thermal = Thermal(i)
|
thermal = Thermal(i)
|
||||||
self._thermal_list.append(thermal)
|
self._thermal_list.append(thermal)
|
||||||
|
|
||||||
# Initialize component list
|
for i in range(MAX_Z9100_COMPONENT):
|
||||||
self._component_name_list.append(COMPONENT_BIOS)
|
component = Component(i)
|
||||||
self._component_name_list.append(SWITCH_CPLD1)
|
self._component_list.append(component)
|
||||||
self._component_name_list.append(SWITCH_CPLD2)
|
|
||||||
self._component_name_list.append(SWITCH_CPLD3)
|
|
||||||
self._component_name_list.append(SWITCH_CPLD4)
|
|
||||||
self._component_name_list.append(SMF_FPGA)
|
|
||||||
|
|
||||||
def _get_pmc_register(self, reg_name):
|
def _get_pmc_register(self, reg_name):
|
||||||
# On successful read, returns the value read from given
|
# On successful read, returns the value read from given
|
||||||
@ -241,82 +230,3 @@ class Chassis(ChassisBase):
|
|||||||
return (self.reset_reason_dict[reset_reason], None)
|
return (self.reset_reason_dict[reset_reason], None)
|
||||||
|
|
||||||
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
||||||
|
|
||||||
def _get_command_result(self, cmdline):
|
|
||||||
try:
|
|
||||||
proc = subprocess.Popen(cmdline, stdout=subprocess.PIPE,
|
|
||||||
shell=True, stderr=subprocess.STDOUT)
|
|
||||||
stdout = proc.communicate()[0]
|
|
||||||
proc.wait()
|
|
||||||
result = stdout.rstrip('\n')
|
|
||||||
except OSError:
|
|
||||||
result = ''
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
def _get_cpld_version(self,cpld_number):
|
|
||||||
io_resource = "/dev/port"
|
|
||||||
CPLD1_VERSION_ADDR = 0x100
|
|
||||||
|
|
||||||
if (cpld_number == 1):
|
|
||||||
fd = os.open(io_resource, os.O_RDONLY)
|
|
||||||
if (fd < 0):
|
|
||||||
return 'NA'
|
|
||||||
if (os.lseek(fd, CPLD1_VERSION_ADDR, os.SEEK_SET)
|
|
||||||
!= CPLD1_VERSION_ADDR):
|
|
||||||
return 'NA'
|
|
||||||
|
|
||||||
buf = os.read(fd, 1)
|
|
||||||
cpld_version = ord(buf)
|
|
||||||
os.close(fd)
|
|
||||||
|
|
||||||
return "%d.%d" % (((cpld_version & 0xF0) >> 4), cpld_version & 0xF)
|
|
||||||
else:
|
|
||||||
cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e"
|
|
||||||
"/iom_cpld_vers").format(12 + cpld_number)
|
|
||||||
|
|
||||||
if (not os.path.isfile(cpld_version_file)):
|
|
||||||
return 'NA'
|
|
||||||
|
|
||||||
try:
|
|
||||||
with open(cpld_version_file, 'r') as fd:
|
|
||||||
ver_str = fd.read()
|
|
||||||
except Exception as error:
|
|
||||||
return 'NA'
|
|
||||||
|
|
||||||
if ver_str == "read error":
|
|
||||||
return 'NA'
|
|
||||||
else:
|
|
||||||
ver_str = ver_str.rstrip("\r\n")
|
|
||||||
cpld_version = int(ver_str.split(":")[1], 16)
|
|
||||||
|
|
||||||
return "%d.%d" % (((cpld_version & 0xF0) >> 4), cpld_version & 0xF)
|
|
||||||
|
|
||||||
def _get_fpga_version(self):
|
|
||||||
fpga_ver = float(self._get_pmc_register('smf_firmware_ver'))
|
|
||||||
return fpga_ver
|
|
||||||
|
|
||||||
def get_firmware_version(self, component_name):
|
|
||||||
"""
|
|
||||||
Retrieves platform-specific hardware/firmware versions for chassis
|
|
||||||
componenets such as BIOS, CPLD, FPGA, etc.
|
|
||||||
Args:
|
|
||||||
component_name: A string, the component name.
|
|
||||||
Returns:
|
|
||||||
A string containing platform-specific component versions
|
|
||||||
"""
|
|
||||||
if component_name in self._component_name_list :
|
|
||||||
if component_name == COMPONENT_BIOS:
|
|
||||||
return self._get_command_result(BIOS_QUERY_VERSION_COMMAND)
|
|
||||||
elif component_name == SWITCH_CPLD1:
|
|
||||||
return self._get_cpld_version(1)
|
|
||||||
elif component_name == SWITCH_CPLD2:
|
|
||||||
return self._get_cpld_version(2)
|
|
||||||
elif component_name == SWITCH_CPLD3:
|
|
||||||
return self._get_cpld_version(3)
|
|
||||||
elif component_name == SWITCH_CPLD4:
|
|
||||||
return self._get_cpld_version(4)
|
|
||||||
elif component_name == SMF_FPGA:
|
|
||||||
return self._get_fpga_version()
|
|
||||||
|
|
||||||
return None
|
|
||||||
|
@ -0,0 +1,164 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# DELLEMC Z9100
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the Components' (e.g., BIOS, CPLD, FPGA, etc.) available in
|
||||||
|
# the platform
|
||||||
|
#
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
try:
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
from sonic_platform_base.component_base import ComponentBase
|
||||||
|
except ImportError as e:
|
||||||
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
BIOS_QUERY_VERSION_COMMAND = "dmidecode -s system-version"
|
||||||
|
|
||||||
|
|
||||||
|
class Component(ComponentBase):
|
||||||
|
"""DellEMC Platform-specific Component class"""
|
||||||
|
|
||||||
|
HWMON_DIR = "/sys/devices/platform/SMF.512/hwmon/"
|
||||||
|
HWMON_NODE = os.listdir(HWMON_DIR)[0]
|
||||||
|
MAILBOX_DIR = HWMON_DIR + HWMON_NODE
|
||||||
|
|
||||||
|
CHASSIS_COMPONENTS = [
|
||||||
|
["BIOS", ("Performs initialization of hardware components during "
|
||||||
|
"booting")],
|
||||||
|
["CPLD1", "Used for managing the system LEDs"],
|
||||||
|
["CPLD2", "Used for managing QSFP28 modules (1-12)"],
|
||||||
|
["CPLD3", "Used for managing QSFP28 modules (13-22)"],
|
||||||
|
["CPLD4", ("Used for managing QSFP28 modules (23-32) and SFP+ "
|
||||||
|
"modules")],
|
||||||
|
["FPGA", ("Platform management controller for on-board temperature "
|
||||||
|
"monitoring, in-chassis power, Fan and LED control")]
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self, component_index=0):
|
||||||
|
self.index = component_index
|
||||||
|
self.name = self.CHASSIS_COMPONENTS[self.index][0]
|
||||||
|
self.description = self.CHASSIS_COMPONENTS[self.index][1]
|
||||||
|
|
||||||
|
def _read_sysfs_file(self, sysfs_file):
|
||||||
|
# On successful read, returns the value read from given
|
||||||
|
# sysfs_file and on failure returns 'ERR'
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
if (not os.path.isfile(sysfs_file)):
|
||||||
|
return rv
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(sysfs_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_command_result(self, cmdline):
|
||||||
|
try:
|
||||||
|
proc = subprocess.Popen(cmdline.split(), stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT)
|
||||||
|
stdout = proc.communicate()[0]
|
||||||
|
proc.wait()
|
||||||
|
result = stdout.rstrip('\n')
|
||||||
|
except OSError:
|
||||||
|
result = None
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def _get_cpld_version(self, cpld_number):
|
||||||
|
io_resource = "/dev/port"
|
||||||
|
CPLD1_VERSION_ADDR = 0x100
|
||||||
|
|
||||||
|
if (cpld_number == 1):
|
||||||
|
fd = os.open(io_resource, os.O_RDONLY)
|
||||||
|
if (fd < 0):
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
if (os.lseek(fd, CPLD1_VERSION_ADDR, os.SEEK_SET)
|
||||||
|
!= CPLD1_VERSION_ADDR):
|
||||||
|
os.close(fd)
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
buf = os.read(fd, 1)
|
||||||
|
cpld_version = str(ord(buf))
|
||||||
|
os.close(fd)
|
||||||
|
|
||||||
|
return cpld_version
|
||||||
|
else:
|
||||||
|
cpld_version_file = ("/sys/class/i2c-adapter/i2c-{0}/{0}-003e"
|
||||||
|
"/iom_cpld_vers").format(12 + cpld_number)
|
||||||
|
ver_str = self._read_sysfs_file(cpld_version_file)
|
||||||
|
|
||||||
|
if (ver_str == "read error") or (ver_str == 'ERR'):
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
ver_str = ver_str.rstrip("\r\n")
|
||||||
|
cpld_version = str(int(ver_str.split(":")[1], 16))
|
||||||
|
|
||||||
|
return cpld_version
|
||||||
|
|
||||||
|
def _get_fpga_version(self):
|
||||||
|
fpga_ver_file = self.MAILBOX_DIR + '/smf_firmware_ver'
|
||||||
|
fpga_ver = self._read_sysfs_file(fpga_ver_file)
|
||||||
|
if (fpga_ver != 'ERR'):
|
||||||
|
return fpga_ver
|
||||||
|
else:
|
||||||
|
return 'NA'
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the name of the component
|
||||||
|
"""
|
||||||
|
return self.name
|
||||||
|
|
||||||
|
def get_description(self):
|
||||||
|
"""
|
||||||
|
Retrieves the description of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the description of the component
|
||||||
|
"""
|
||||||
|
return self.description
|
||||||
|
|
||||||
|
def get_firmware_version(self):
|
||||||
|
"""
|
||||||
|
Retrieves the firmware version of the component
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the firmware version of the component
|
||||||
|
"""
|
||||||
|
if self.index == 0: # BIOS
|
||||||
|
bios_ver = self._get_command_result(BIOS_QUERY_VERSION_COMMAND)
|
||||||
|
|
||||||
|
if not bios_ver:
|
||||||
|
return 'NA'
|
||||||
|
else:
|
||||||
|
return bios_ver
|
||||||
|
|
||||||
|
elif self.index < 5: # CPLD
|
||||||
|
return self._get_cpld_version(self.index)
|
||||||
|
elif self.index == 5: # FPGA
|
||||||
|
return self._get_fpga_version()
|
||||||
|
|
||||||
|
def install_firmware(self, image_path):
|
||||||
|
"""
|
||||||
|
Installs firmware to the component
|
||||||
|
|
||||||
|
Args:
|
||||||
|
image_path: A string, path to firmware image
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A boolean, True if install was successful, False if not
|
||||||
|
"""
|
||||||
|
return False
|
Reference in New Issue
Block a user