Merge pull request #3381 from ArunSaravananBalachandran/platform2.0
DellEMC : Platform2.0 API Implementation for Chassis [S6000, S6100, Z9100], Fan [S6000]
This commit is contained in:
commit
a62ab7890e
@ -11,18 +11,34 @@ try:
|
|||||||
import os
|
import os
|
||||||
import time
|
import time
|
||||||
import datetime
|
import datetime
|
||||||
|
import subprocess
|
||||||
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
|
||||||
|
from sonic_platform.eeprom import Eeprom
|
||||||
|
from sonic_platform.fan import Fan
|
||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
|
||||||
|
MAX_S6000_FAN = 3
|
||||||
|
|
||||||
|
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):
|
||||||
"""
|
"""
|
||||||
DELLEMC Platform-specific Chassis class
|
DELLEMC Platform-specific Chassis class
|
||||||
"""
|
"""
|
||||||
|
CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0"
|
||||||
MAILBOX_DIR = "/sys/devices/platform/dell-s6000-cpld.0"
|
|
||||||
|
|
||||||
sfp_control = ""
|
sfp_control = ""
|
||||||
PORT_START = 0
|
PORT_START = 0
|
||||||
@ -54,9 +70,20 @@ class Chassis(ChassisBase):
|
|||||||
# Get Transceiver status
|
# Get Transceiver status
|
||||||
self.modprs_register = self._get_transceiver_status()
|
self.modprs_register = self._get_transceiver_status()
|
||||||
|
|
||||||
def get_register(self, reg_name):
|
self.sys_eeprom = Eeprom()
|
||||||
|
for i in range(MAX_S6000_FAN):
|
||||||
|
fan = Fan(i)
|
||||||
|
self._fan_list.append(fan)
|
||||||
|
|
||||||
|
# Initialize component list
|
||||||
|
self._component_name_list.append(COMPONENT_BIOS)
|
||||||
|
self._component_name_list.append(COMPONENT_CPLD1)
|
||||||
|
self._component_name_list.append(COMPONENT_CPLD2)
|
||||||
|
self._component_name_list.append(COMPONENT_CPLD3)
|
||||||
|
|
||||||
|
def _get_cpld_register(self, reg_name):
|
||||||
rv = 'ERR'
|
rv = 'ERR'
|
||||||
mb_reg_file = self.MAILBOX_DIR+'/'+reg_name
|
mb_reg_file = self.CPLD_DIR+'/'+reg_name
|
||||||
|
|
||||||
if (not os.path.isfile(mb_reg_file)):
|
if (not os.path.isfile(mb_reg_file)):
|
||||||
return rv
|
return rv
|
||||||
@ -71,11 +98,85 @@ class Chassis(ChassisBase):
|
|||||||
rv = rv.lstrip(" ")
|
rv = rv.lstrip(" ")
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the chassis
|
||||||
|
Returns:
|
||||||
|
string: The name of the chassis
|
||||||
|
"""
|
||||||
|
return self.sys_eeprom.modelstr()
|
||||||
|
|
||||||
|
def get_presence(self):
|
||||||
|
"""
|
||||||
|
Retrieves the presence of the chassis
|
||||||
|
Returns:
|
||||||
|
bool: True if chassis is present, False if not
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the model number (or part number) of the chassis
|
||||||
|
Returns:
|
||||||
|
string: Model/part number of chassis
|
||||||
|
"""
|
||||||
|
return self.sys_eeprom.part_number_str()
|
||||||
|
|
||||||
|
def get_serial(self):
|
||||||
|
"""
|
||||||
|
Retrieves the serial number of the chassis (Service tag)
|
||||||
|
Returns:
|
||||||
|
string: Serial number of chassis
|
||||||
|
"""
|
||||||
|
return self.sys_eeprom.serial_str()
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the chassis
|
||||||
|
Returns:
|
||||||
|
bool: A boolean value, True if chassis is operating properly
|
||||||
|
False if not
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def get_base_mac(self):
|
||||||
|
"""
|
||||||
|
Retrieves the base MAC address for the chassis
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the MAC address in the format
|
||||||
|
'XX:XX:XX:XX:XX:XX'
|
||||||
|
"""
|
||||||
|
return self.sys_eeprom.base_mac_addr()
|
||||||
|
|
||||||
|
def get_serial_number(self):
|
||||||
|
"""
|
||||||
|
Retrieves the hardware serial number for the chassis
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string containing the hardware serial number for this
|
||||||
|
chassis.
|
||||||
|
"""
|
||||||
|
return self.sys_eeprom.serial_number_str()
|
||||||
|
|
||||||
|
def get_system_eeprom_info(self):
|
||||||
|
"""
|
||||||
|
Retrieves the full content of system EEPROM information for the
|
||||||
|
chassis
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A dictionary where keys are the type code defined in
|
||||||
|
OCP ONIE TlvInfo EEPROM format and values are their
|
||||||
|
corresponding values.
|
||||||
|
"""
|
||||||
|
return self.sys_eeprom.system_eeprom_info()
|
||||||
|
|
||||||
def get_reboot_cause(self):
|
def get_reboot_cause(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the cause of the previous reboot
|
Retrieves the cause of the previous reboot
|
||||||
"""
|
"""
|
||||||
reset_reason = int(self.get_register('last_reboot_reason'), base=16)
|
reset_reason = int(self._get_cpld_register('last_reboot_reason'),
|
||||||
|
base=16)
|
||||||
|
|
||||||
# In S6000, We track the reboot reason by writing the reason in
|
# In S6000, We track the reboot reason by writing the reason in
|
||||||
# NVRAM. Only Warmboot and Coldboot reason are supported here.
|
# NVRAM. Only Warmboot and Coldboot reason are supported here.
|
||||||
@ -85,6 +186,46 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
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_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:
|
||||||
@ -151,3 +292,4 @@ class Chassis(ChassisBase):
|
|||||||
return True, {}
|
return True, {}
|
||||||
return False, {}
|
return False, {}
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,8 @@ psu_eeprom_format = [
|
|||||||
fan_eeprom_format = [
|
fan_eeprom_format = [
|
||||||
('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7),
|
('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7),
|
||||||
('Part Number', 's', 10), ('Part Num Revision', 's', 3),
|
('Part Number', 's', 10), ('Part Num Revision', 's', 3),
|
||||||
('Mfg Test', 's', 2), ('Number of Fans', 's', 2), ('Fan Type', 's', 1),
|
('Mfg Test', 's', 2), ('Redundant copy', 's', 82),
|
||||||
|
('Number of Fans', 's', 1), ('Fan Type', 's', 1),
|
||||||
('Fab Rev', 's', 2)
|
('Fab Rev', 's', 2)
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -86,6 +87,8 @@ class Eeprom(TlvInfoDecoder):
|
|||||||
self.base_mac = 'NA'
|
self.base_mac = 'NA'
|
||||||
self.serial_number = 'NA'
|
self.serial_number = 'NA'
|
||||||
self.part_number = 'NA'
|
self.part_number = 'NA'
|
||||||
|
self.model_str = 'NA'
|
||||||
|
self.serial = 'NA'
|
||||||
self.eeprom_tlv_dict = dict()
|
self.eeprom_tlv_dict = dict()
|
||||||
else:
|
else:
|
||||||
eeprom = self.eeprom_data
|
eeprom = self.eeprom_data
|
||||||
@ -95,6 +98,8 @@ class Eeprom(TlvInfoDecoder):
|
|||||||
self.base_mac = 'NA'
|
self.base_mac = 'NA'
|
||||||
self.serial_number = 'NA'
|
self.serial_number = 'NA'
|
||||||
self.part_number = 'NA'
|
self.part_number = 'NA'
|
||||||
|
self.model_str = 'NA'
|
||||||
|
self.serial = 'NA'
|
||||||
return
|
return
|
||||||
|
|
||||||
total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10])
|
total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10])
|
||||||
@ -123,11 +128,15 @@ class Eeprom(TlvInfoDecoder):
|
|||||||
tlv_index += ord(eeprom[tlv_index+1]) + 2
|
tlv_index += ord(eeprom[tlv_index+1]) + 2
|
||||||
|
|
||||||
self.base_mac = self.eeprom_tlv_dict.get(
|
self.base_mac = self.eeprom_tlv_dict.get(
|
||||||
hex(self._TLV_CODE_MAC_BASE), 'NA')
|
"0x%X" % (self._TLV_CODE_MAC_BASE), 'NA')
|
||||||
self.serial_number = self.eeprom_tlv_dict.get(
|
self.serial_number = self.eeprom_tlv_dict.get(
|
||||||
hex(self._TLV_CODE_SERIAL_NUMBER), 'NA')
|
"0x%X" % (self._TLV_CODE_SERIAL_NUMBER), 'NA')
|
||||||
self.part_number = self.eeprom_tlv_dict.get(
|
self.part_number = self.eeprom_tlv_dict.get(
|
||||||
hex(self._TLV_CODE_PART_NUMBER), 'NA')
|
"0x%X" % (self._TLV_CODE_PART_NUMBER), 'NA')
|
||||||
|
self.model_str = self.eeprom_tlv_dict.get(
|
||||||
|
"0x%X" % (self._TLV_CODE_PRODUCT_NAME), 'NA')
|
||||||
|
self.serial = self.eeprom_tlv_dict.get(
|
||||||
|
"0x%X" % (self._TLV_CODE_SERVICE_TAG), 'NA')
|
||||||
|
|
||||||
def _load_device_eeprom(self):
|
def _load_device_eeprom(self):
|
||||||
"""
|
"""
|
||||||
@ -151,7 +160,7 @@ class Eeprom(TlvInfoDecoder):
|
|||||||
if valid:
|
if valid:
|
||||||
self.serial_number += "-" + data
|
self.serial_number += "-" + data
|
||||||
else:
|
else:
|
||||||
seld.serial_number = 'NA'
|
self.serial_number = 'NA'
|
||||||
|
|
||||||
(valid, data) = self._get_eeprom_field("Part Number")
|
(valid, data) = self._get_eeprom_field("Part Number")
|
||||||
if valid:
|
if valid:
|
||||||
@ -159,6 +168,12 @@ class Eeprom(TlvInfoDecoder):
|
|||||||
else:
|
else:
|
||||||
self.part_number = 'NA'
|
self.part_number = 'NA'
|
||||||
|
|
||||||
|
(valid, data) = self._get_eeprom_field("Fan Type")
|
||||||
|
if valid:
|
||||||
|
self.fan_type = data
|
||||||
|
else:
|
||||||
|
self.fan_type = 'NA'
|
||||||
|
|
||||||
def _get_eeprom_field(self, field_name):
|
def _get_eeprom_field(self, field_name):
|
||||||
"""
|
"""
|
||||||
For a field name specified in the EEPROM format, returns the
|
For a field name specified in the EEPROM format, returns the
|
||||||
@ -185,6 +200,12 @@ class Eeprom(TlvInfoDecoder):
|
|||||||
"""
|
"""
|
||||||
return self.part_number
|
return self.part_number
|
||||||
|
|
||||||
|
def airflow_fan_type(self):
|
||||||
|
"""
|
||||||
|
Returns the airflow fan type.
|
||||||
|
"""
|
||||||
|
return int(self.fan_type.encode('hex'), 16)
|
||||||
|
|
||||||
# System EEPROM specific methods
|
# System EEPROM specific methods
|
||||||
def base_mac_addr(self):
|
def base_mac_addr(self):
|
||||||
"""
|
"""
|
||||||
@ -192,6 +213,18 @@ class Eeprom(TlvInfoDecoder):
|
|||||||
"""
|
"""
|
||||||
return self.base_mac
|
return self.base_mac
|
||||||
|
|
||||||
|
def modelstr(self):
|
||||||
|
"""
|
||||||
|
Returns the Model name.
|
||||||
|
"""
|
||||||
|
return self.model_str
|
||||||
|
|
||||||
|
def serial_str(self):
|
||||||
|
"""
|
||||||
|
Returns the servicetag number.
|
||||||
|
"""
|
||||||
|
return self.serial
|
||||||
|
|
||||||
def system_eeprom_info(self):
|
def system_eeprom_info(self):
|
||||||
"""
|
"""
|
||||||
Returns a dictionary, where keys are the type code defined in
|
Returns a dictionary, where keys are the type code defined in
|
||||||
|
@ -0,0 +1,286 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
########################################################################
|
||||||
|
# DellEMC S6000
|
||||||
|
#
|
||||||
|
# Module contains an implementation of SONiC Platform Base API and
|
||||||
|
# provides the Fans' information which are available in the platform
|
||||||
|
#
|
||||||
|
########################################################################
|
||||||
|
|
||||||
|
|
||||||
|
try:
|
||||||
|
import os
|
||||||
|
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")
|
||||||
|
|
||||||
|
|
||||||
|
MAX_S6000_FAN_SPEED = 19000
|
||||||
|
|
||||||
|
|
||||||
|
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):
|
||||||
|
# Fan is 1-based in DellEMC platforms
|
||||||
|
self.index = fan_index + 1
|
||||||
|
self.is_psu_fan = psu_fan
|
||||||
|
|
||||||
|
if not self.is_psu_fan:
|
||||||
|
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.max_fan_speed = MAX_S6000_FAN_SPEED
|
||||||
|
self.supported_led_color = ['off', 'green', 'amber']
|
||||||
|
else:
|
||||||
|
self.get_fan_speed_reg = self.I2C_DIR + "i2c-1/1-005{}/" +\
|
||||||
|
"fan1_input".format(10 - self.index)
|
||||||
|
|
||||||
|
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'
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
if (not os.path.isfile(reg_file)):
|
||||||
|
return rv
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(reg_file, 'r') as fd:
|
||||||
|
rv = fd.read()
|
||||||
|
except:
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
rv = rv.rstrip('\r\n')
|
||||||
|
rv = rv.lstrip(" ")
|
||||||
|
return rv
|
||||||
|
|
||||||
|
def _set_i2c_register(self, reg_file, value):
|
||||||
|
# On successful write, the value read will be written on
|
||||||
|
# reg_name and on failure returns 'ERR'
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
if (not os.path.isfile(reg_file)):
|
||||||
|
return rv
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(reg_file, 'w') as fd:
|
||||||
|
rv = fd.write(str(value))
|
||||||
|
except:
|
||||||
|
rv = 'ERR'
|
||||||
|
|
||||||
|
return rv
|
||||||
|
|
||||||
|
def get_name(self):
|
||||||
|
"""
|
||||||
|
Retrieves the name of the Fan
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
string: The name of the Fan
|
||||||
|
"""
|
||||||
|
if not self.is_psu_fan:
|
||||||
|
return "Fan{}".format(self.index)
|
||||||
|
else:
|
||||||
|
return "PSU{} Fan".format(self.index)
|
||||||
|
|
||||||
|
def get_presence(self):
|
||||||
|
"""
|
||||||
|
Retrieves the presence of the Fan Unit
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if Fan is present, False if not
|
||||||
|
"""
|
||||||
|
status = False
|
||||||
|
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
|
||||||
|
|
||||||
|
def get_model(self):
|
||||||
|
"""
|
||||||
|
Retrieves the part number of the Fan
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
string: Part number of Fan
|
||||||
|
"""
|
||||||
|
return self.eeprom.part_number_str()
|
||||||
|
|
||||||
|
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"
|
||||||
|
return self.eeprom.serial_number_str()
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the Fan
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
bool: True if Fan is operating properly, False if not
|
||||||
|
"""
|
||||||
|
status = False
|
||||||
|
fan_speed = self._get_i2c_register(self.get_fan_speed_reg)
|
||||||
|
if (fan_speed != 'ERR'):
|
||||||
|
if (int(fan_speed) > 14000):
|
||||||
|
status = True
|
||||||
|
|
||||||
|
return status
|
||||||
|
|
||||||
|
def get_direction(self):
|
||||||
|
"""
|
||||||
|
Retrieves the fan airflow direction
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string, either FAN_DIRECTION_INTAKE or
|
||||||
|
FAN_DIRECTION_EXHAUST depending on fan direction
|
||||||
|
"""
|
||||||
|
direction = {1: 'FAN_DIRECTION_INTAKE', 2: 'FAN_DIRECTION_EXHAUST'}
|
||||||
|
fan_direction = self.eeprom.airflow_fan_type()
|
||||||
|
|
||||||
|
return direction.get(fan_direction,'NA')
|
||||||
|
|
||||||
|
def get_speed(self):
|
||||||
|
"""
|
||||||
|
Retrieves the speed of fan
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
int: percentage of the max fan speed
|
||||||
|
"""
|
||||||
|
fan_speed = self._get_i2c_register(self.get_fan_speed_reg)
|
||||||
|
if (fan_speed != 'ERR') and self.get_presence():
|
||||||
|
speed_in_rpm = int(fan_speed, 10)
|
||||||
|
speed = (100 * speed_in_rpm)/self.max_fan_speed
|
||||||
|
else:
|
||||||
|
speed = 0
|
||||||
|
|
||||||
|
return speed
|
||||||
|
|
||||||
|
def get_speed_tolerance(self):
|
||||||
|
"""
|
||||||
|
Retrieves the speed tolerance of the fan
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An integer, the percentage of variance from target speed
|
||||||
|
which is considered tolerable
|
||||||
|
"""
|
||||||
|
if self.get_presence():
|
||||||
|
# The tolerance value is fixed as 20% for all the DellEmc platform
|
||||||
|
tolerance = 20
|
||||||
|
else:
|
||||||
|
tolerance = 0
|
||||||
|
|
||||||
|
return tolerance
|
||||||
|
|
||||||
|
def set_speed(self, speed):
|
||||||
|
"""
|
||||||
|
Set fan speed to expected value
|
||||||
|
Args:
|
||||||
|
speed: An integer, the percentage of full fan speed to set
|
||||||
|
fan to, in the range 0 (off) to 100 (full 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)
|
||||||
|
if (rv != 'ERR'):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
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.
|
||||||
|
"""
|
||||||
|
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.fan_led_reg ,color)
|
||||||
|
if (rv != 'ERR'):
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_status_led(self):
|
||||||
|
"""
|
||||||
|
Gets the state of the fan status LED
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A string, one of the predefined STATUS_LED_COLOR_* strings.
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
|
||||||
|
def get_target_speed(self):
|
||||||
|
"""
|
||||||
|
Retrieves the target (expected) speed of the fan
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
An integer, the percentage of full fan speed, in the range 0
|
||||||
|
(off) to 100 (full speed)
|
||||||
|
"""
|
||||||
|
return 79
|
@ -15,7 +15,6 @@ try:
|
|||||||
import subprocess
|
import subprocess
|
||||||
import glob
|
import glob
|
||||||
import sonic_device_util
|
import sonic_device_util
|
||||||
from commands import getstatusoutput
|
|
||||||
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
|
||||||
@ -32,6 +31,12 @@ MAX_S6100_FAN = 4
|
|||||||
MAX_S6100_PSU = 2
|
MAX_S6100_PSU = 2
|
||||||
MAX_S6100_THERMAL = 10
|
MAX_S6100_THERMAL = 10
|
||||||
|
|
||||||
|
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):
|
||||||
"""
|
"""
|
||||||
@ -54,8 +59,6 @@ class Chassis(ChassisBase):
|
|||||||
power_reason_dict[33] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC
|
power_reason_dict[33] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC
|
||||||
power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED
|
power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED
|
||||||
|
|
||||||
_component_name_list = ["BIOS", "CPLD1", "CPLD2", "FPGA"]
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
|
||||||
ChassisBase.__init__(self)
|
ChassisBase.__init__(self)
|
||||||
@ -77,6 +80,11 @@ class Chassis(ChassisBase):
|
|||||||
thermal = Thermal(i)
|
thermal = Thermal(i)
|
||||||
self._thermal_list.append(thermal)
|
self._thermal_list.append(thermal)
|
||||||
|
|
||||||
|
# Initialize component list
|
||||||
|
self._component_name_list.append(COMPONENT_BIOS)
|
||||||
|
self._component_name_list.append(SWITCH_CPLD)
|
||||||
|
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
|
||||||
# reg_name and on failure returns 'ERR'
|
# reg_name and on failure returns 'ERR'
|
||||||
@ -111,36 +119,45 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the chassis
|
||||||
Returns:
|
Returns:
|
||||||
string: The name of the device
|
string: The name of the chassis
|
||||||
"""
|
"""
|
||||||
return self.sys_eeprom.modelstr()
|
return self.sys_eeprom.modelstr()
|
||||||
|
|
||||||
def get_presence(self):
|
def get_presence(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the presence of the device
|
Retrieves the presence of the chassis
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if device is present, False if not
|
bool: True if chassis is present, False if not
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_model(self):
|
def get_model(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the model number (or part number) of the device
|
Retrieves the model number (or part number) of the chassis
|
||||||
Returns:
|
Returns:
|
||||||
string: Model/part number of device
|
string: Model/part number of chassis
|
||||||
"""
|
"""
|
||||||
return self.sys_eeprom.part_number_str()
|
return self.sys_eeprom.part_number_str()
|
||||||
|
|
||||||
def get_serial(self):
|
def get_serial(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the serial number of the device (Service tag)
|
Retrieves the serial number of the chassis (Service tag)
|
||||||
Returns:
|
Returns:
|
||||||
string: Serial number of device
|
string: Serial number of chassis
|
||||||
"""
|
"""
|
||||||
return self.sys_eeprom.serial_str()
|
return self.sys_eeprom.serial_str()
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the chassis
|
||||||
|
Returns:
|
||||||
|
bool: A boolean value, True if chassis is operating properly
|
||||||
|
False if not
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
def get_base_mac(self):
|
def get_base_mac(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the base MAC address for the chassis
|
Retrieves the base MAC address for the chassis
|
||||||
@ -156,7 +173,8 @@ class Chassis(ChassisBase):
|
|||||||
Retrieves the hardware serial number for the chassis
|
Retrieves the hardware serial number for the chassis
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
A string containing the hardware serial number for this chassis.
|
A string containing the hardware serial number for this
|
||||||
|
chassis.
|
||||||
"""
|
"""
|
||||||
return self.sys_eeprom.serial_number_str()
|
return self.sys_eeprom.serial_number_str()
|
||||||
|
|
||||||
@ -200,35 +218,57 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
||||||
|
|
||||||
def get_component_name_list(self):
|
def _get_command_result(self, cmdline):
|
||||||
"""
|
try:
|
||||||
Retrieves chassis components list such as BIOS, CPLD, FPGA, etc.
|
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 = ''
|
||||||
|
|
||||||
Returns:
|
return result
|
||||||
A list containing component name.
|
|
||||||
"""
|
def _get_cpld_version(self):
|
||||||
return self._component_name_list
|
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):
|
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()
|
||||||
|
|
||||||
version = None
|
return None
|
||||||
|
|
||||||
if component_name in self._component_name_list:
|
|
||||||
|
|
||||||
if component_name == self._component_name_list[0]: # BIOS
|
|
||||||
status, version = getstatusoutput(
|
|
||||||
"dmidecode -s system-version")
|
|
||||||
|
|
||||||
elif component_name == self._component_name_list[1]: # CPLD1
|
|
||||||
version = None
|
|
||||||
|
|
||||||
elif component_name == self._component_name_list[2]: # CPLD2
|
|
||||||
version = None
|
|
||||||
|
|
||||||
elif component_name == self._component_name_list[3]: # SMF
|
|
||||||
version = None
|
|
||||||
|
|
||||||
return version
|
|
||||||
|
|
||||||
def install_component_firmware(self, component_name, image_path):
|
def install_component_firmware(self, component_name, image_path):
|
||||||
|
|
||||||
@ -250,7 +290,7 @@ class Chassis(ChassisBase):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if component_name in self._component_name_list:
|
if component_name in self._component_name_list:
|
||||||
if component_name == self._component_name_list[0]: # BIOS
|
if component_name == COMPONENT_BIOS: # BIOS
|
||||||
|
|
||||||
# current BIOS version
|
# current BIOS version
|
||||||
current_bios_version = self.get_firmware_version("BIOS")
|
current_bios_version = self.get_firmware_version("BIOS")
|
||||||
@ -310,16 +350,14 @@ class Chassis(ChassisBase):
|
|||||||
image_path
|
image_path
|
||||||
self.run_command(command)
|
self.run_command(command)
|
||||||
|
|
||||||
elif component_name == self._component_name_list[1]: # CPLD1
|
elif component_name == SWITCH_CPLD: # CPLD
|
||||||
return False
|
return False
|
||||||
|
|
||||||
elif component_name == self._component_name_list[2]: # CPLD2
|
elif component_name == SMF_FPGA: # SMF
|
||||||
return False
|
|
||||||
|
|
||||||
elif component_name == self._component_name_list[3]: # SMF
|
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print "Invalid component Name:", component_name
|
print "Invalid component Name:", component_name
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
@ -209,6 +209,18 @@ class Fan(FanBase):
|
|||||||
status = False
|
status = False
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
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_status():
|
||||||
|
return self.STATUS_LED_COLOR_GREEN
|
||||||
|
else:
|
||||||
|
return self.STATUS_LED_COLOR_OFF
|
||||||
|
|
||||||
def get_target_speed(self):
|
def get_target_speed(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the target (expected) speed of the fan
|
Retrieves the target (expected) speed of the fan
|
||||||
|
@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import os
|
import os
|
||||||
|
import subprocess
|
||||||
|
import re
|
||||||
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
|
||||||
from sonic_platform.fan import Fan
|
from sonic_platform.fan import Fan
|
||||||
@ -17,10 +19,20 @@ try:
|
|||||||
except ImportError as e:
|
except ImportError as e:
|
||||||
raise ImportError(str(e) + "- required module not found")
|
raise ImportError(str(e) + "- required module not found")
|
||||||
|
|
||||||
|
|
||||||
MAX_Z9100_FANTRAY = 5
|
MAX_Z9100_FANTRAY = 5
|
||||||
MAX_Z9100_FAN = 2
|
MAX_Z9100_FAN = 2
|
||||||
MAX_Z9100_PSU = 2
|
MAX_Z9100_PSU = 2
|
||||||
|
|
||||||
|
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):
|
||||||
"""
|
"""
|
||||||
@ -92,6 +104,14 @@ class Chassis(ChassisBase):
|
|||||||
fan = Fan(i, j)
|
fan = Fan(i, j)
|
||||||
self._fan_list.append(fan)
|
self._fan_list.append(fan)
|
||||||
|
|
||||||
|
# Initialize component list
|
||||||
|
self._component_name_list.append(COMPONENT_BIOS)
|
||||||
|
self._component_name_list.append(SWITCH_CPLD1)
|
||||||
|
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
|
||||||
# reg_name and on failure returns 'ERR'
|
# reg_name and on failure returns 'ERR'
|
||||||
@ -113,36 +133,45 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
def get_name(self):
|
def get_name(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the name of the device
|
Retrieves the name of the chassis
|
||||||
Returns:
|
Returns:
|
||||||
string: The name of the device
|
string: The name of the chassis
|
||||||
"""
|
"""
|
||||||
return self.sys_eeprom.modelstr()
|
return self.sys_eeprom.modelstr()
|
||||||
|
|
||||||
def get_presence(self):
|
def get_presence(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the presence of the device
|
Retrieves the presence of the chassis
|
||||||
Returns:
|
Returns:
|
||||||
bool: True if device is present, False if not
|
bool: True if chassis is present, False if not
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_model(self):
|
def get_model(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the model number (or part number) of the device
|
Retrieves the model number (or part number) of the chassis
|
||||||
Returns:
|
Returns:
|
||||||
string: Model/part number of device
|
string: Model/part number of chassis
|
||||||
"""
|
"""
|
||||||
return self.sys_eeprom.part_number_str()
|
return self.sys_eeprom.part_number_str()
|
||||||
|
|
||||||
def get_serial(self):
|
def get_serial(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the serial number of the device (Service tag)
|
Retrieves the serial number of the chassis (Service tag)
|
||||||
Returns:
|
Returns:
|
||||||
string: Serial number of device
|
string: Serial number of chassis
|
||||||
"""
|
"""
|
||||||
return self.sys_eeprom.serial_str()
|
return self.sys_eeprom.serial_str()
|
||||||
|
|
||||||
|
def get_status(self):
|
||||||
|
"""
|
||||||
|
Retrieves the operational status of the chassis
|
||||||
|
Returns:
|
||||||
|
bool: A boolean value, True if chassis is operating properly
|
||||||
|
False if not
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
def get_base_mac(self):
|
def get_base_mac(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the base MAC address for the chassis
|
Retrieves the base MAC address for the chassis
|
||||||
@ -172,7 +201,6 @@ class Chassis(ChassisBase):
|
|||||||
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
|
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
|
||||||
to pass a description of the reboot cause.
|
to pass a description of the reboot cause.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
reset_reason = int(self._get_pmc_register('smf_reset_reason'))
|
reset_reason = int(self._get_pmc_register('smf_reset_reason'))
|
||||||
power_reason = int(self._get_pmc_register('smf_poweron_reason'))
|
power_reason = int(self._get_pmc_register('smf_poweron_reason'))
|
||||||
|
|
||||||
@ -192,3 +220,81 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
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
|
||||||
|
@ -208,6 +208,18 @@ class Fan(FanBase):
|
|||||||
status = False
|
status = False
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
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_status():
|
||||||
|
return self.STATUS_LED_COLOR_GREEN
|
||||||
|
else:
|
||||||
|
return self.STATUS_LED_COLOR_OFF
|
||||||
|
|
||||||
def get_target_speed(self):
|
def get_target_speed(self):
|
||||||
"""
|
"""
|
||||||
Retrieves the target (expected) speed of the fan
|
Retrieves the target (expected) speed of the fan
|
||||||
|
Loading…
Reference in New Issue
Block a user