Skip to content

Commit

Permalink
[device/celestica]: Add firmware management api based on the new plat…
Browse files Browse the repository at this point in the history
…form API (#3013)
  • Loading branch information
Wirut Getbamrung authored and jleveque committed Jul 2, 2019
1 parent 4f737f8 commit 1616f48
Show file tree
Hide file tree
Showing 7 changed files with 403 additions and 86 deletions.
67 changes: 25 additions & 42 deletions device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.fan import Fan
from sonic_platform.psu import Psu
from sonic_platform.device import Device
from sonic_platform.component import Component
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

MMC_CPLD_ADDR = '0x100'
BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version"
CONFIG_DB_PATH = "/etc/sonic/config_db.json"
SMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/version"
MMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/getreg"
NUM_FAN = 3
NUM_PSU = 2

Expand All @@ -42,16 +40,8 @@ def __init__(self):
psu = Psu(index)
self._psu_list.append(psu)
ChassisBase.__init__(self)

def __get_register_value(self, path, register):
cmd = "echo {1} > {0}; cat {0}".format(path, register)
p = subprocess.Popen(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
raw_data, err = p.communicate()
if err is not '':
return 'None'
else:
return raw_data.strip()
self._component_device = Device("component")
self._component_name_list = self._component_device.get_name_list()

def __read_config_db(self):
try:
Expand All @@ -75,39 +65,32 @@ def get_base_mac(self):
except KeyError:
raise KeyError("Base MAC not found")

def get_component_versions(self):
def get_firmware_version(self, component_name):
"""
Retrieves platform-specific hardware/firmware versions for chassis
componenets such as BIOS, CPLD, FPGA, etc.
Args:
type: A string, component name
Returns:
A string containing platform-specific component versions
"""
self.component = Component(component_name)
if component_name not in self._component_name_list:
return None
return self.component.get_firmware_version()

component_versions = dict()

# Get BIOS version
try:
with open(BIOS_VERSION_PATH, 'r') as fd:
bios_version = fd.read()
except IOError:
raise IOError("Unable to open version file !")

# Get CPLD version
cpld_version = dict()

with open(SMC_CPLD_PATH, 'r') as fd:
smc_cpld_version = fd.read()
smc_cpld_version = 'None' if smc_cpld_version is 'None' else "{}.{}".format(
int(smc_cpld_version[2], 16), int(smc_cpld_version[3], 16))

mmc_cpld_version = self.__get_register_value(
MMC_CPLD_PATH, MMC_CPLD_ADDR)
mmc_cpld_version = 'None' if mmc_cpld_version is 'None' else "{}.{}".format(
int(mmc_cpld_version[2], 16), int(mmc_cpld_version[3], 16))

cpld_version["SMC"] = smc_cpld_version
cpld_version["MMC"] = mmc_cpld_version
def install_component_firmware(self, component_name, image_path):
"""
Install firmware to module
Args:
type: A string, component name.
image_path: A string, path to firmware image.
component_versions["CPLD"] = cpld_version
component_versions["BIOS"] = bios_version.strip()
return str(component_versions)
Returns:
A boolean, True if install successfully, False if not
"""
self.component = Component(component_name)
if component_name not in self._component_name_list:
return False
return self.component.upgrade_firmware(image_path)
128 changes: 128 additions & 0 deletions device/celestica/x86_64-cel_e1031-r0/sonic_platform/component.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
#!/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
import shutil
import shlex
import subprocess

try:
from sonic_platform_base.device_base import DeviceBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

MMC_CPLD_ADDR = '0x100'
BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version"
CONFIG_DB_PATH = "/etc/sonic/config_db.json"
SMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/version"
MMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/getreg"


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

DEVICE_TYPE = "component"

def __init__(self, component_name):
DeviceBase.__init__(self)
self.name = component_name.upper()

def __run_command(self, command):
# Run bash command and print output to stdout
try:
process = subprocess.Popen(
shlex.split(command), stdout=subprocess.PIPE)
while True:
output = process.stdout.readline()
if output == '' and process.poll() is not None:
break
rc = process.poll()
if rc != 0:
return False
except:
return False
return True

def __get_register_value(self, path, register):
# Retrieves the cpld register value
cmd = "echo {1} > {0}; cat {0}".format(path, register)
p = subprocess.Popen(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
raw_data, err = p.communicate()
if err is not '':
return None
return raw_data.strip()

def __get_bios_version(self):
# Retrieves the BIOS firmware version
try:
with open(BIOS_VERSION_PATH, 'r') as fd:
bios_version = fd.read()
return bios_version.strip()
except Exception as e:
return None

def __get_cpld_version(self):
# Retrieves the CPLD firmware version
cpld_version = dict()
with open(SMC_CPLD_PATH, 'r') as fd:
smc_cpld_version = fd.read()
smc_cpld_version = 'None' if smc_cpld_version is 'None' else "{}.{}".format(
int(smc_cpld_version[2], 16), int(smc_cpld_version[3], 16))

mmc_cpld_version = self.__get_register_value(
MMC_CPLD_PATH, MMC_CPLD_ADDR)
mmc_cpld_version = 'None' if mmc_cpld_version is 'None' else "{}.{}".format(
int(mmc_cpld_version[2], 16), int(mmc_cpld_version[3], 16))

cpld_version["SMC_CPLD"] = smc_cpld_version
cpld_version["MMC_CPLD"] = mmc_cpld_version
return cpld_version

def get_firmware_version(self):
"""
Retrieves the firmware version of module
Returns:
string: The firmware versions of the module
"""
fw_version = None

if self.name == "BIOS":
fw_version = self.__get_bios_version()
elif "CPLD" in self.name:
cpld_version = self.__get_cpld_version()
fw_version = cpld_version.get(self.name)

return fw_version

def upgrade_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
"""
if not os.path.isfile(image_path):
return False

if "CPLD" in self.name:
img_name = os.path.basename(image_path)
root, ext = os.path.splitext(img_name)
ext = ".vme" if ext == "" else ext
new_image_path = os.path.join("/tmp", (root.lower() + ext))
shutil.copy(image_path, new_image_path)
install_command = "ispvm %s" % new_image_path
elif self.name == "BIOS":
print("Not supported")
return False

return self.__run_command(install_command)
47 changes: 47 additions & 0 deletions device/celestica/x86_64-cel_e1031-r0/sonic_platform/device.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/usr/bin/env python

#############################################################################
# Celestica
#
# Device contains an implementation of SONiC Platform Base API and
# provides the device information
#
#############################################################################

try:
from sonic_platform_base.device_base import DeviceBase
except ImportError as e:
raise ImportError(str(e) + "- required module not found")


class Device(DeviceBase):
"""Platform-specific Device class"""

COMPONENTS_NAME = ["SMC_CPLD", "MMC_CPLD", "BIOS"]

def __init__(self, device_type, index=None):
self.device_type = device_type
self.index = index
DeviceBase.__init__(self)

def get_name(self):
"""
Retrieves the name of the device
Returns:
string: The name of the device
"""
device_name = {
"component": self.COMPONENTS_NAME[self.index]
}.get(self.device_type, None)
return device_name

def get_name_list(self):
"""
Retrieves list of the device name that available in this device type
Returns:
string: The list of device name
"""
name_list = {
"component": self.COMPONENTS_NAME
}.get(self.device_type, None)
return name_list
68 changes: 25 additions & 43 deletions device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,14 @@
from sonic_platform_base.chassis_base import ChassisBase
from sonic_platform.fan import Fan
from sonic_platform.psu import Psu
from sonic_platform.device import Device
from sonic_platform.component import Component
except ImportError as e:
raise ImportError(str(e) + "- required module not found")

BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version"
GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg"
CONFIG_DB_PATH = "/etc/sonic/config_db.json"
NUM_FAN = 5
NUM_PSU = 2
CPLD_ADDR_MAPPING = {
"CPLD1": "0x100",
"CPLD2": "0x200",
"CPLD3": "0x280",
"CPLD4": "0x300",
"CPLD5": "0x380"
}


class Chassis(ChassisBase):
Expand All @@ -47,16 +40,8 @@ def __init__(self):
psu = Psu(index)
self._psu_list.append(psu)
ChassisBase.__init__(self)

def __get_register_value(self, path, register):
cmd = "echo {1} > {0}; cat {0}".format(path, register)
p = subprocess.Popen(
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
raw_data, err = p.communicate()
if err is not '':
return 'None'
else:
return raw_data.strip()
self._component_device = Device("component")
self._component_name_list = self._component_device.get_name_list()

def __read_config_db(self):
try:
Expand All @@ -80,35 +65,32 @@ def get_base_mac(self):
except KeyError:
raise KeyError("Base MAC not found")

def get_component_versions(self):
def get_firmware_version(self, component_name):
"""
Retrieves platform-specific hardware/firmware versions for chassis
componenets such as BIOS, CPLD, FPGA, etc.
Args:
type: A string, component name
Returns:
A string containing platform-specific component versions
"""
self.component = Component(component_name)
if component_name not in self._component_name_list:
return None
return self.component.get_firmware_version()

component_versions = dict()

# Get BIOS version
try:
with open(BIOS_VERSION_PATH, 'r') as fd:
bios_version = fd.read()
except IOError:
raise IOError("Unable to open version file !")
def install_component_firmware(self, component_name, image_path):
"""
Install firmware to module
Args:
type: A string, component name.
image_path: A string, path to firmware image.
# Get CPLD version
cpld_version = dict()
for cpld_name in CPLD_ADDR_MAPPING:
try:
cpld_addr = CPLD_ADDR_MAPPING[cpld_name]
cpld_version_raw = self.__get_register_value(
GETREG_PATH, cpld_addr)
cpld_version_str = "{}.{}".format(int(cpld_version_raw[2], 16), int(
cpld_version_raw[3], 16)) if cpld_version_raw is not None else 'None'
cpld_version[cpld_name] = cpld_version_str
except Exception, e:
cpld_version[cpld_name] = 'None'
component_versions["CPLD"] = cpld_version
component_versions["BIOS"] = bios_version.strip()
return str(component_versions)
Returns:
A boolean, True if install successfully, False if not
"""
self.component = Component(component_name)
if component_name not in self._component_name_list:
return False
return self.component.upgrade_firmware(image_path)
Loading

0 comments on commit 1616f48

Please sign in to comment.