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]: Add firmware management api based on the new platform API #3013

Merged
merged 6 commits into from
Jul 2, 2019
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
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