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:
Sujin Kang 2019-09-16 12:25:01 -07:00 committed by GitHub
commit a62ab7890e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 691 additions and 62 deletions

View File

@ -11,18 +11,34 @@ try:
import os
import time
import datetime
import subprocess
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.sfp import Sfp
from sonic_platform.eeprom import Eeprom
from sonic_platform.fan import Fan
except ImportError as e:
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):
"""
DELLEMC Platform-specific Chassis class
"""
MAILBOX_DIR = "/sys/devices/platform/dell-s6000-cpld.0"
CPLD_DIR = "/sys/devices/platform/dell-s6000-cpld.0"
sfp_control = ""
PORT_START = 0
@ -54,9 +70,20 @@ class Chassis(ChassisBase):
# 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'
mb_reg_file = self.MAILBOX_DIR+'/'+reg_name
mb_reg_file = self.CPLD_DIR+'/'+reg_name
if (not os.path.isfile(mb_reg_file)):
return rv
@ -71,11 +98,85 @@ class Chassis(ChassisBase):
rv = rv.lstrip(" ")
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):
"""
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
# NVRAM. Only Warmboot and Coldboot reason are supported here.
@ -85,6 +186,46 @@ class Chassis(ChassisBase):
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):
presence_ctrl = self.sfp_control + 'qsfp_modprs'
try:
@ -151,3 +292,4 @@ class Chassis(ChassisBase):
return True, {}
return False, {}

View File

@ -35,7 +35,8 @@ psu_eeprom_format = [
fan_eeprom_format = [
('PPID', 's', 20), ('DPN Rev', 's', 3), ('Service Tag', 's', 7),
('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)
]
@ -86,6 +87,8 @@ class Eeprom(TlvInfoDecoder):
self.base_mac = 'NA'
self.serial_number = 'NA'
self.part_number = 'NA'
self.model_str = 'NA'
self.serial = 'NA'
self.eeprom_tlv_dict = dict()
else:
eeprom = self.eeprom_data
@ -95,6 +98,8 @@ class Eeprom(TlvInfoDecoder):
self.base_mac = 'NA'
self.serial_number = 'NA'
self.part_number = 'NA'
self.model_str = 'NA'
self.serial = 'NA'
return
total_length = (ord(eeprom[9]) << 8) | ord(eeprom[10])
@ -123,11 +128,15 @@ class Eeprom(TlvInfoDecoder):
tlv_index += ord(eeprom[tlv_index+1]) + 2
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(
hex(self._TLV_CODE_SERIAL_NUMBER), 'NA')
"0x%X" % (self._TLV_CODE_SERIAL_NUMBER), 'NA')
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):
"""
@ -151,7 +160,7 @@ class Eeprom(TlvInfoDecoder):
if valid:
self.serial_number += "-" + data
else:
seld.serial_number = 'NA'
self.serial_number = 'NA'
(valid, data) = self._get_eeprom_field("Part Number")
if valid:
@ -159,6 +168,12 @@ class Eeprom(TlvInfoDecoder):
else:
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):
"""
For a field name specified in the EEPROM format, returns the
@ -185,6 +200,12 @@ class Eeprom(TlvInfoDecoder):
"""
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
def base_mac_addr(self):
"""
@ -192,6 +213,18 @@ class Eeprom(TlvInfoDecoder):
"""
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):
"""
Returns a dictionary, where keys are the type code defined in

View File

@ -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

View File

@ -15,7 +15,6 @@ try:
import subprocess
import glob
import sonic_device_util
from commands import getstatusoutput
from sonic_platform_base.platform_base import PlatformBase
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.sfp import Sfp
@ -32,6 +31,12 @@ MAX_S6100_FAN = 4
MAX_S6100_PSU = 2
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):
"""
@ -54,8 +59,6 @@ class Chassis(ChassisBase):
power_reason_dict[33] = ChassisBase.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC
power_reason_dict[44] = ChassisBase.REBOOT_CAUSE_INSUFFICIENT_FAN_SPEED
_component_name_list = ["BIOS", "CPLD1", "CPLD2", "FPGA"]
def __init__(self):
ChassisBase.__init__(self)
@ -77,6 +80,11 @@ class Chassis(ChassisBase):
thermal = Thermal(i)
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):
# On successful read, returns the value read from given
# reg_name and on failure returns 'ERR'
@ -111,36 +119,45 @@ class Chassis(ChassisBase):
def get_name(self):
"""
Retrieves the name of the device
Retrieves the name of the chassis
Returns:
string: The name of the device
string: The name of the chassis
"""
return self.sys_eeprom.modelstr()
def get_presence(self):
"""
Retrieves the presence of the device
Retrieves the presence of the chassis
Returns:
bool: True if device is present, False if not
bool: True if chassis is present, False if not
"""
return True
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:
string: Model/part number of device
string: Model/part number of chassis
"""
return self.sys_eeprom.part_number_str()
def get_serial(self):
"""
Retrieves the serial number of the device (Service tag)
Retrieves the serial number of the chassis (Service tag)
Returns:
string: Serial number of device
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
@ -156,7 +173,8 @@ class Chassis(ChassisBase):
Retrieves the hardware serial number for the chassis
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()
@ -200,35 +218,57 @@ class Chassis(ChassisBase):
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
def get_component_name_list(self):
"""
Retrieves chassis components list such as BIOS, CPLD, FPGA, etc.
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 = ''
Returns:
A list containing component name.
"""
return self._component_name_list
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()
version = 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
return None
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 == self._component_name_list[0]: # BIOS
if component_name == COMPONENT_BIOS: # BIOS
# current BIOS version
current_bios_version = self.get_firmware_version("BIOS")
@ -310,16 +350,14 @@ class Chassis(ChassisBase):
image_path
self.run_command(command)
elif component_name == self._component_name_list[1]: # CPLD1
elif component_name == SWITCH_CPLD: # CPLD
return False
elif component_name == self._component_name_list[2]: # CPLD2
return False
elif component_name == self._component_name_list[3]: # SMF
elif component_name == SMF_FPGA: # SMF
return False
else:
print "Invalid component Name:", component_name
return True

View File

@ -209,6 +209,18 @@ class Fan(FanBase):
status = False
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):
"""
Retrieves the target (expected) speed of the fan

View File

@ -10,6 +10,8 @@
try:
import os
import subprocess
import re
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.sfp import Sfp
from sonic_platform.fan import Fan
@ -17,10 +19,20 @@ try:
except ImportError as e:
raise ImportError(str(e) + "- required module not found")
MAX_Z9100_FANTRAY = 5
MAX_Z9100_FAN = 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):
"""
@ -92,6 +104,14 @@ class Chassis(ChassisBase):
fan = Fan(i, j)
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):
# On successful read, returns the value read from given
# reg_name and on failure returns 'ERR'
@ -113,36 +133,45 @@ class Chassis(ChassisBase):
def get_name(self):
"""
Retrieves the name of the device
Retrieves the name of the chassis
Returns:
string: The name of the device
string: The name of the chassis
"""
return self.sys_eeprom.modelstr()
def get_presence(self):
"""
Retrieves the presence of the device
Retrieves the presence of the chassis
Returns:
bool: True if device is present, False if not
bool: True if chassis is present, False if not
"""
return True
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:
string: Model/part number of device
string: Model/part number of chassis
"""
return self.sys_eeprom.part_number_str()
def get_serial(self):
"""
Retrieves the serial number of the device (Service tag)
Retrieves the serial number of the chassis (Service tag)
Returns:
string: Serial number of device
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
@ -172,7 +201,6 @@ class Chassis(ChassisBase):
is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used
to pass a description of the reboot cause.
"""
reset_reason = int(self._get_pmc_register('smf_reset_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")
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

View File

@ -208,6 +208,18 @@ class Fan(FanBase):
status = False
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):
"""
Retrieves the target (expected) speed of the fan