Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[device/celestica]: Implement Silverstone platform API [THERMAL/COMPONENT] #3938

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,19 @@

try:
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.component import Component
from sonic_platform.eeprom import Tlv
from sonic_platform.fan import Fan
from sonic_platform.psu import Psu
from sonic_platform.thermal import Thermal
from helper import APIHelper
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

NUM_FAN_TRAY = 7
NUM_FAN = 2
NUM_PSU = 2
NUM_THERMAL = 5
NUM_THERMAL = 10
NUM_SFP = 32
NUM_COMPONENT = 5

Expand All @@ -50,6 +52,12 @@ def __init__(self):
for index in range(0, NUM_PSU):
psu = Psu(index)
self._psu_list.append(psu)
for index in range(0, NUM_COMPONENT):
component = Component(index)
self._component_list.append(component)
for index in range(0, NUM_THERMAL):
thermal = Thermal(index)
self._thermal_list.append(thermal)

def get_base_mac(self):
"""
Expand Down Expand Up @@ -92,7 +100,8 @@ def get_reboot_cause(self):

status, raw_cause = self._api_helper.ipmi_raw(
IPMI_OEM_NETFN, IPMI_GET_REBOOT_CAUSE)
hx_cause = raw_cause.split()[0] if status else 00
hx_cause = raw_cause.split()[0] if status and len(
raw_cause.split()) > 0 else 00
reboot_cause = {
"00": self.REBOOT_CAUSE_HARDWARE_OTHER,
"11": self.REBOOT_CAUSE_POWER_LOSS,
Expand Down
121 changes: 121 additions & 0 deletions device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#!/usr/bin/env python

#############################################################################
# Celestica
#
# Component contains an implementation of SONiC Platform Base API and
# provides the components firmware management function
#
#############################################################################

import json
import os.path

try:
from sonic_platform_base.component_base import ComponentBase
from helper import APIHelper
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

COMPONENT_LIST = [
("BIOS", "Basic Input/Output System"),
("BMC", "Baseboard Management Controller"),
("SWITCH_CPLD", "Switch board CPLD"),
("BASE_CPLD", "Base board CPLD"),
("FPGA", "Field-programmable gate array")
]
SW_CPLD_VER_PATH = "/sys/module/switch_cpld/version"
BASE_CPLD_VER_PATH = "/sys/module/baseboard_lpc/version"
CPLD_UPGRADE_OPT = 4
BIOS_VER_PATH = "/sys/class/dmi/id/bios_version"
BIOS__UPGRADE_OPT = 2
BMC_VER_CMD = "ipmitool mc info | grep 'Firmware Revision'"
BMC_UPGRADE_OPT = 1
CFUFLASH_FW_UPGRADE_CMD = "CFUFLASH -cd -d {} -mse 3 {}"
MEM_PCI_RESOURCE = "/sys/bus/pci/devices/0000:09:00.0/resource0"
FPGA_VER_MEM_OFFSET = 0


class Component(ComponentBase):
"""Platform-specific Component class"""

DEVICE_TYPE = "component"

def __init__(self, component_index):
ComponentBase.__init__(self)
self.index = component_index
self.name = self.get_name()
self._api_helper = APIHelper()

def __get_bmc_ver(self):
bmc_ver = "Unknown"
status, raw_bmc_data = self._api_helper.run_command(BMC_VER_CMD)
if status:
bmc_ver_data = raw_bmc_data.split(":")
bmc_ver = bmc_ver_data[-1].strip() if len(
bmc_ver_data) > 1 else bmc_ver
return bmc_ver

def __get_fpga_ver(self):
fpga_ver = "Unknown"
status, reg_val = self._api_helper.pci_get_value(
MEM_PCI_RESOURCE, FPGA_VER_MEM_OFFSET)
if status:
major = reg_val[0] >> 16
minor = int(bin(reg_val[0])[16:32], 2)
fpga_ver = '{}.{}'.format(major, minor)
return fpga_ver

def get_name(self):
"""
Retrieves the name of the component
Returns:
A string containing the name of the component
"""
return COMPONENT_LIST[self.index][0]

def get_description(self):
"""
Retrieves the description of the component
Returns:
A string containing the description of the component
"""
return COMPONENT_LIST[self.index][1]

def get_firmware_version(self):
"""
Retrieves the firmware version of module
Returns:
string: The firmware versions of the module
"""
fw_version = {
"BIOS": self._api_helper.read_txt_file(BIOS_VER_PATH),
"BMC": self.__get_bmc_ver(),
"FPGA": self.__get_fpga_ver(),
"SWITCH_CPLD": self._api_helper.read_txt_file(SW_CPLD_VER_PATH),
"BASE_CPLD": self._api_helper.read_txt_file(BASE_CPLD_VER_PATH),
}.get(self.name, "Unknown")

return fw_version

def install_firmware(self, image_path):
"""
Install firmware to module
Args:
image_path: A string, path to firmware image
Returns:
A boolean, True if install successfully, False if not
"""
install_command = {
"BMC": CFUFLASH_FW_UPGRADE_CMD.format(BMC_UPGRADE_OPT, image_path),
"BIOS": CFUFLASH_FW_UPGRADE_CMD.format(BIOS__UPGRADE_OPT, image_path),
"SWITCH_CPLD": CFUFLASH_FW_UPGRADE_CMD.format(CPLD_UPGRADE_OPT, image_path),
"BASE_CPLD": CFUFLASH_FW_UPGRADE_CMD.format(CPLD_UPGRADE_OPT, image_path)
}.get(self.name, None)

if not os.path.isfile(image_path) or install_command is None:
return False

# print(install_command)
status = self._api_helper.run_interactive_command(install_command)
return status
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#!/usr/bin/env python

import os
import struct
import subprocess

from mmap import *

HOST_CHK_CMD = "docker > /dev/null 2>&1"
EMPTY_STRING = ""
Expand All @@ -16,6 +17,39 @@ def __init__(self):
def is_host(self):
return os.system(HOST_CHK_CMD) == 0

def pci_get_value(self, resource, offset):
status = True
result = ""
try:
fd = os.open(resource, os.O_RDWR)
mm = mmap(fd, 0)
mm.seek(int(offset))
read_data_stream = mm.read(4)
result = struct.unpack('I', read_data_stream)
except:
status = False
return status, result

def run_command(self, cmd):
status = True
result = ""
try:
p = subprocess.Popen(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
raw_data, err = p.communicate()
if err == '':
result = raw_data.strip()
except:
status = False
return status, result

def run_interactive_command(self, cmd):
try:
os.system(cmd)
except:
return False
return True

def read_txt_file(self, file_path):
try:
with open(file_path, 'r') as fd:
Expand All @@ -35,6 +69,8 @@ def ipmi_raw(self, netfn, cmd):
raw_data, err = p.communicate()
if err == '':
result = raw_data.strip()
else:
status = False
except:
status = False
return status, result
Expand All @@ -51,6 +87,24 @@ def ipmi_fru_id(self, id, key=None):
raw_data, err = p.communicate()
if err == '':
result = raw_data.strip()
else:
status = False
except:
status = False
return status, result

def ipmi_set_ss_thres(self, id, threshold_key, value):
status = True
result = ""
try:
cmd = "ipmitool sensor thresh '{}' {} {}".format(str(id), str(threshold_key), str(value))
p = subprocess.Popen(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
raw_data, err = p.communicate()
if err == '':
result = raw_data.strip()
else:
status = False
except:
status = False
return status, result
Loading