From 8c21a147a06598a6d32e39b614f9e8241f97dc38 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Wed, 3 Apr 2019 16:00:31 +0800 Subject: [PATCH 1/3] [platform/cel] Implement FAN APIs based on the new platform API --- platform/broadcom/platform-modules-cel.mk | 8 + .../cel-platform-api/setup.py | 29 ++ .../sonic_platform_api/__init__.py | 0 .../sonic_platform_api/chassis.py | 148 +++++++++ .../sonic_platform_api/fan.py | 310 ++++++++++++++++++ .../sonic_platform_api/platform.py | 23 ++ .../debian/platform-modules-dx010.init | 58 ++-- .../dx010/modules/dx010_cpld.c | 81 ++++- 8 files changed, 634 insertions(+), 23 deletions(-) create mode 100644 platform/broadcom/sonic-platform-modules-cel/cel-platform-api/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/platform.py diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index 1224faaa6750..0535c6b3ee9d 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -17,3 +17,11 @@ $(CEL_HALIBURTON_PLATFORM_MODULE)_PLATFORM = x86_64-cel_e1031-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_HALIBURTON_PLATFORM_MODULE))) SONIC_STRETCH_DEBS += $(CEL_DX010_PLATFORM_MODULE) + +# Celestica platform api package +SONIC_PLATFORM_API_CEL_VERSION = 0.1 + +SONIC_PLATFORM_API_PY2 = cel_platform_api-$(SONIC_PLATFORM_API_CEL_VERSION)-py2-none-any.whl +$(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cel/cel-platform-api +$(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 +SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2) diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/setup.py b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/setup.py new file mode 100644 index 000000000000..29a63e0cb7da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/setup.py @@ -0,0 +1,29 @@ +from setuptools import setup + +setup( + name='cel-platform-api', + version='0.1', + description='SONiC platform management API implementation for Celestica platform', + license='Apache 2.0', + author='SONiC Team', + author_email='linuxnetdev@microsoft.com', + url='https://github.com/Azure/sonic-buildimage', + maintainer='Wirut Getbamrung', + maintainer_email='wgetbumr@celestica.com', + packages=[ + 'sonic_platform_api', + ], + classifiers=[ + 'Development Status :: 3 - Alpha', + 'Environment :: Plugins', + 'Intended Audience :: Developers', + 'Intended Audience :: Information Technology', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: Apache Software License', + 'Natural Language :: English', + 'Operating System :: POSIX :: Linux', + 'Programming Language :: Python :: 2.7', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform-api PLATFORM-API', +) diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/__init__.py b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/chassis.py b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/chassis.py new file mode 100644 index 000000000000..afc49abc61aa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/chassis.py @@ -0,0 +1,148 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import re +import os +import subprocess +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform_api.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + ChassisBase.__init__(self) + self.config_data = {} + self.config_db_path = "/etc/sonic/config_db.json" + self.platform = self.get_platform() + NUM_FAN = { + "x86_64-cel_e1031-r0": 3, + "x86_64-cel_seastone-r0": 5 + }.get(self.platform, 0) + for index in range(0, NUM_FAN): + fan = Fan(index) + self._fan_list.append(fan) + self.bios_version_path = "/sys/class/dmi/id/bios_version" + self.smc_cpld_e1031_path = "/sys/devices/platform/e1031.smc/version" + self.mmc_cpld_e1031_path = "/sys/devices/platform/e1031.smc/getreg" + self.cpld_dx010_path = "/sys/devices/platform/dx010_cpld/getreg" + + 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() + + def __read_config_db(self): + try: + with open(self.config_db_path, 'r') as fd: + data = json.load(fd) + return data + except IOError: + raise IOError("Unable to open config_db file !") + + def get_platform(self): + try: + self.config_data = self.__read_config_db() + platform = self.config_data["DEVICE_METADATA"]["localhost"]["platform"] + return platform + except KeyError: + raise KeyError("Platform name not found") + + 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' + """ + try: + self.config_data = self.__read_config_db() + base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] + return str(base_mac) + except KeyError: + raise KeyError("Base MAC not found") + + def get_component_versions(self): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Returns: + A string containing platform-specific component versions + """ + + component_versions = dict() + + # Get BIOS version + try: + with open(self.bios_version_path, 'r') as fd: + bios_version = fd.read() + except IOError: + raise IOError("Unable to open version file !") + + # Get CPLD version + if self.platform == "x86_64-cel_seastone-r0": + + CPLD_1 = self.__get_register_value(self.cpld_dx010_path, '0x100') + CPLD_2 = self.__get_register_value(self.cpld_dx010_path, '0x200') + CPLD_3 = self.__get_register_value(self.cpld_dx010_path, '0x280') + CPLD_4 = self.__get_register_value(self.cpld_dx010_path, '0x300') + CPLD_5 = self.__get_register_value(self.cpld_dx010_path, '0x380') + + CPLD_1 = 'None' if CPLD_1 is 'None' else "{}.{}".format( + int(CPLD_1[2], 16), int(CPLD_1[3], 16)) + CPLD_2 = 'None' if CPLD_2 is 'None' else "{}.{}".format( + int(CPLD_2[2], 16), int(CPLD_2[3], 16)) + CPLD_3 = 'None' if CPLD_3 is 'None' else "{}.{}".format( + int(CPLD_3[2], 16), int(CPLD_3[3], 16)) + CPLD_4 = 'None' if CPLD_4 is 'None' else "{}.{}".format( + int(CPLD_4[2], 16), int(CPLD_4[3], 16)) + CPLD_5 = 'None' if CPLD_5 is 'None' else "{}.{}".format( + int(CPLD_5[2], 16), int(CPLD_5[3], 16)) + + cpld_version = dict() + cpld_version["CPLD1"] = CPLD_1 + cpld_version["CPLD2"] = CPLD_2 + cpld_version["CPLD3"] = CPLD_3 + cpld_version["CPLD4"] = CPLD_4 + cpld_version["CPLD5"] = CPLD_5 + component_versions["CPLD"] = cpld_version + + elif self.platform == "x86_64-cel_e1031-r0": + cpld_version = dict() + + with open(self.smc_cpld_e1031_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( + self.mmc_cpld_e1031_path, '0x100') + 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 + + component_versions["CPLD"] = cpld_version + + component_versions["BIOS"] = bios_version.strip() + return str(component_versions) diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/fan.py b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/fan.py new file mode 100644 index 000000000000..796c2e1cdae1 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/fan.py @@ -0,0 +1,310 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import json +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_index): + FanBase.__init__(self) + self.index = fan_index + self.config_data = {} + self.config_db_path = "/etc/sonic/config_db.json" + self.platform = self.get_platform() + self.fan_speed = 0 + self.fan_emc2305_path = "/sys/bus/i2c/drivers/emc2305/" + self.sys_gpio_dir = "/sys/class/gpio" + self.fan_em2305_max_pwm = 255 + self.fan_emc2305_pwm = "pwm{}" + self.fan_emc2305_target = "fan{}_target" + self.fan_emc2305_input = "pwm{}" + + # dx010 fan attributes + # Two EMC2305s located at i2c-13-4d and i2c-13-2e + # to control a dual-fan module. + self.dx010_emc2305_chip = [ + { + 'device': "13-002e", + 'index_map': [2, 1, 4, 5, 3] + }, + { + 'device': "13-004d", + 'index_map': [2, 4, 5, 3, 1] + } + ] + + self.dx010_fan_gpio = [ + {'base': self.get_gpio_base()}, + {'prs': 10, 'dir': 15, 'color': {'red': 31, 'green': 32}}, + {'prs': 11, 'dir': 16, 'color': {'red': 29, 'green': 30}}, + {'prs': 12, 'dir': 17, 'color': {'red': 35, 'green': 36}}, + {'prs': 13, 'dir': 18, 'color': {'red': 37, 'green': 38}}, + {'prs': 14, 'dir': 19, 'color': {'red': 33, 'green': 34}}, + ] + + # e1031 fan attributes + # Single emc2305 chip located at i2c-23-4d + # to control a fan module + self.e1031_emc2305_chip = [ + { + 'device': "23-004d", + 'index_map': [1, 2, 4] + } + ] + self.fan_e1031_path = "/sys/devices/platform/e1031.smc/" + # TODO: Add fan presence status in sysfs + self.fan_e1031_presence = "fan{}_prs" + self.fan_e1031_direction = "fan{}_dir" + self.fan_e1031_led = "fan{}_led" + self.fan_e1031_led_col_map = { + self.STATUS_LED_COLOR_GREEN: "green", + self.STATUS_LED_COLOR_RED: "amber", + self.STATUS_LED_COLOR_OFF: "off" + } + + def __read_config_db(self): + try: + with open(self.config_db_path, 'r') as fd: + data = json.load(fd) + return data + except IOError: + raise IOError("Unable to open config_db file !") + + def get_platform(self): + try: + self.config_data = self.__read_config_db() + platform = self.config_data["DEVICE_METADATA"]["localhost"]["platform"] + return platform + except KeyError: + raise KeyError("Platform name not found") + + def get_gpio_base(self): + for r in os.listdir(self.sys_gpio_dir): + if "gpiochip" in r: + return int(r[8:], 10) + return 216 # Reserve + + def get_gpio_value(self, pinnum): + gpio_base = self.dx010_fan_gpio[0]['base'] + + gpio_dir = self.sys_gpio_dir + '/gpio' + str(gpio_base+pinnum) + gpio_file = gpio_dir + "/value" + + try: + with open(gpio_file, 'r') as fd: + retval = fd.read() + except IOError: + raise IOError("Unable to open " + gpio_file + "file !") + + retval = retval.rstrip('\r\n') + return retval + + def set_gpio_value(self, pinnum, value=0): + gpio_base = self.dx010_fan_gpio[0]['base'] + + gpio_dir = self.sys_gpio_dir + '/gpio' + str(gpio_base+pinnum) + gpio_file = gpio_dir + "/value" + + try: + with open(gpio_file, 'w') as fd: + retval = fd.write(str(value)) + except IOError: + raise IOError("Unable to open " + gpio_file + "file !") + + def get_direction(self): + + direction = self.FAN_DIRECTION_INTAKE + + if self.platform == "x86_64-cel_seastone-r0": + raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['dir']) + if int(raw, 10) == 0: + direction = self.FAN_DIRECTION_INTAKE + else: + direction = self.FAN_DIRECTION_EXHAUST + + elif self.platform == "x86_64-cel_e1031-r0": + try: + fan_direction_file = (self.fan_e1031_path + + self.fan_e1031_direction.format(self.index+1)) + with open(fan_direction_file, 'r') as file: + raw = file.read().strip('\r\n') + if str(raw).upper() == "F2B": + direction = self.FAN_DIRECTION_INTAKE + else: + direction = self.FAN_DIRECTION_EXHAUST + except IOError: + return False + + return direction + + def get_speed(self): + """ + DX010 and E1031 platform specific data: + + speed = pwm_in/255*100 + """ + # TODO: Seperate PSU's fan and main fan class + if self.fan_speed != 0: + return self.fan_speed + else: + speed = 0 + pwm = [] + emc2305_chips = {} + + if self.platform == "x86_64-cel_seastone-r0": + emc2305_chips = self.dx010_emc2305_chip + elif self.platform == "x86_64-cel_e1031-r0": + emc2305_chips = self.e1031_emc2305_chip + else: + return 0 + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + self.fan_emc2305_path, device, self.fan_emc2305_input) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'r') as file: + raw = file.read().strip('\r\n') + pwm.append(int(raw, 10)) + except IOError: + raise IOError("Unable to open " + sysfs_path) + + speed = math.ceil( + float(pwm[0]) * 100 / self.fan_em2305_max_pwm) + + return int(speed) + + def get_target_speed(self): + """ + DX010 and E1031 platform specific data: + + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + + """ + target = 0 + pwm = [] + emc2305_chips = {} + + if self.platform == "x86_64-cel_seastone-r0": + emc2305_chips = self.dx010_emc2305_chip + elif self.platform == "x86_64-cel_e1031-r0": + emc2305_chips = self.e1031_emc2305_chip + else: + return target + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + self.fan_emc2305_path, device, self.fan_emc2305_target) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'r') as file: + raw = file.read().strip('\r\n') + pwm.append(int(raw, 10)) + except IOError: + raise IOError("Unable to open " + sysfs_path) + + target = pwm[0] * 100 / self.fan_em2305_max_pwm + + return target + + 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 + """ + return 10 + + def set_speed(self, speed): + """ + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + """ + pwm = speed * 255 / 100 + emc2305_chips = {} + + if self.platform == "x86_64-cel_seastone-r0": + emc2305_chips = self.dx010_emc2305_chip + elif self.platform == "x86_64-cel_e1031-r0": + emc2305_chips = self.e1031_emc2305_chip + else: + return False + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + self.fan_emc2305_path, device, self.fan_emc2305_pwm) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'w') as file: + file.write(str(int(pwm))) + except IOError: + return False + + return True + + def set_status_led(self, color): + + if self.platform == "x86_64-cel_seastone-r0": + try: + if color == self.STATUS_LED_COLOR_GREEN: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 1) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 0) + + elif color == self.STATUS_LED_COLOR_RED: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 0) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 1) + + elif color == self.STATUS_LED_COLOR_OFF: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 1) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 1) + else: + return False + + except IOError: + return False + + elif self.platform == "x86_64-cel_e1031-r0": + try: + fan_led_file = (self.fan_e1031_path + + self.fan_e1031_led.format(self.index+1)) + with open(fan_led_file, 'r') as file: + file.write(self.fan_e1031_led_col_map[color]) + except IOError: + return False + + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/platform.py b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/platform.py new file mode 100644 index 000000000000..9b5d780e42c4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform_api.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init index 2117ab22b402..aa13d572be78 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-dx010.init @@ -12,7 +12,8 @@ ### END INIT INFO function export_gpio { -label=$2 +label=$3 +gpio_dir=$2 gpio_num=$1 gpio_base=`( cat /sys/class/gpio/gpiochip*/base | head -1 ) 2>/dev/null` gpio_label=`( cat /sys/class/gpio/gpiochip*/label | head -1 ) 2>/dev/null` @@ -27,6 +28,13 @@ if [ $? -ne 0 ]; then echo "Platform driver error: Cannot export gpio$ionum!" exit 1; fi +if [[ "X$gpio_dir" != "X" ]]; then + echo $gpio_dir > /sys/class/gpio/gpio${ionum}/direction + if [ $? -ne 0 ]; then + echo "Platform driver error: Cannot set direction of gpio$ionum!" + exit 1; + fi +fi } case "$1" in @@ -95,27 +103,33 @@ start) sleep 2 # Export platform gpio sysfs - export_gpio 10 # Fan 1 present - export_gpio 11 # Fan 2 present - export_gpio 12 # Fan 3 present - export_gpio 13 # Fan 4 present - export_gpio 14 # Fan 5 present - - export_gpio 22 # PSU L PWOK - export_gpio 25 # PSU R PWOK - export_gpio 27 # PSU L ABS - export_gpio 28 # PSU R ABS - - export_gpio 29 # Fan 1 LED: Red - export_gpio 30 # Fan 1 LED: Yellow - export_gpio 31 # Fan 2 LED: Red - export_gpio 32 # Fan 2 LED: Yellow - export_gpio 33 # Fan 3 LED: Red - export_gpio 34 # Fan 3 LED: Yellow - export_gpio 35 # Fan 4 LED: Red - export_gpio 36 # Fan 4 LED: Yellow - export_gpio 37 # Fan 5 LED: Red - export_gpio 38 # Fan 5 LED: Yellow + export_gpio 10 "in" # Fan 1 present + export_gpio 11 "in" # Fan 2 present + export_gpio 12 "in" # Fan 3 present + export_gpio 13 "in" # Fan 4 present + export_gpio 14 "in" # Fan 5 present + + export_gpio 15 "in" # Fan 1 direction + export_gpio 16 "in" # Fan 2 direction + export_gpio 17 "in" # Fan 3 direction + export_gpio 18 "in" # Fan 4 direction + export_gpio 19 "in" # Fan 5 direction + + export_gpio 22 "in" # PSU L PWOK + export_gpio 25 "in" # PSU R PWOK + export_gpio 27 "in" # PSU L ABS + export_gpio 28 "in" # PSU R ABS + + export_gpio 29 "out" # Fan 1 LED: Red + export_gpio 30 "out" # Fan 1 LED: Yellow + export_gpio 31 "out" # Fan 2 LED: Red + export_gpio 32 "out" # Fan 2 LED: Yellow + export_gpio 33 "out" # Fan 3 LED: Red + export_gpio 34 "out" # Fan 3 LED: Yellow + export_gpio 35 "out" # Fan 4 LED: Red + export_gpio 36 "out" # Fan 4 LED: Yellow + export_gpio 37 "out" # Fan 5 LED: Red + export_gpio 38 "out" # Fan 5 LED: Yellow # Turn off/down lpmod by defult (0 - Normal, 1 - Low Pow) echo 0x00000000 > /sys/devices/platform/dx010_cpld/qsfp_lpmode diff --git a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c index 397361a5edd6..7893220ff6d5 100644 --- a/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c +++ b/platform/broadcom/sonic-platform-modules-cel/dx010/modules/dx010_cpld.c @@ -30,6 +30,13 @@ #define DRIVER_NAME "dx010_cpld" +#define CPLD1_VERSION_ADDR 0x100 +#define CPLD2_VERSION_ADDR 0x200 +#define CPLD3_VERSION_ADDR 0x280 +#define CPLD4_VERSION_ADDR 0x300 +#define CPLD5_VERSION_ADDR 0x380 + + #define RESET0108 0x250 #define RESET0910 0x251 #define RESET1118 0x2d0 @@ -110,10 +117,36 @@ struct dx010_i2c_data { struct dx010_cpld_data { struct i2c_adapter *i2c_adapter[LENGTH_PORT_CPLD]; struct mutex cpld_lock; + uint16_t read_addr; }; struct dx010_cpld_data *cpld_data; +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + + uint16_t addr; + char *last; + + addr = (uint16_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + cpld_data->read_addr = addr; + return count; +} + +static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + + int len = 0; + mutex_lock(&cpld_data->cpld_lock); + len = sprintf(buf, "0x%2.2x\n",inb(cpld_data->read_addr)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} + static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, char *buf) { @@ -134,6 +167,47 @@ static ssize_t get_reset(struct device *dev, struct device_attribute *devattr, return sprintf(buf,"0x%8.8lx\n", reset & 0xffffffff); } +static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + + uint16_t addr; + uint8_t value; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&cpld_data->cpld_lock); + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + addr = (uint16_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + + outb(value,addr); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} + static ssize_t set_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { @@ -248,12 +322,16 @@ static ssize_t get_modirq(struct device *dev, struct device_attribute *devattr, return sprintf(buf,"0x%8.8lx\n", irq & 0xffffffff); } +static DEVICE_ATTR_RW(getreg); +static DEVICE_ATTR_WO(setreg); static DEVICE_ATTR(qsfp_reset, S_IRUGO | S_IWUSR, get_reset, set_reset); static DEVICE_ATTR(qsfp_lpmode, S_IRUGO | S_IWUSR, get_lpmode, set_lpmode); static DEVICE_ATTR(qsfp_modprs, S_IRUGO, get_modprs, NULL); static DEVICE_ATTR(qsfp_modirq, S_IRUGO, get_modirq, NULL); static struct attribute *dx010_lpc_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, &dev_attr_qsfp_reset.attr, &dev_attr_qsfp_lpmode.attr, &dev_attr_qsfp_modprs.attr, @@ -499,6 +577,7 @@ static int cel_dx010_lpc_drv_probe(struct platform_device *pdev) return -ENOMEM; mutex_init(&cpld_data->cpld_lock); + cpld_data->read_addr = CPLD1_VERSION_ADDR; res = platform_get_resource(pdev, IORESOURCE_IO, 0); if (unlikely(!res)) { @@ -558,4 +637,4 @@ module_exit(cel_dx010_lpc_exit); MODULE_AUTHOR("Abhisit Sangjan "); MODULE_AUTHOR("Pariwat Leamsumran "); MODULE_DESCRIPTION("Celestica SeaStone DX010 LPC Driver"); -MODULE_LICENSE("GPL"); +MODULE_LICENSE("GPL"); \ No newline at end of file From df97ce3ddf488fda3714b46f26888f62d9b1198f Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Tue, 23 Apr 2019 14:52:25 +0700 Subject: [PATCH 2/3] [platform/cel] Move platform api to under device platform --- .../sonic_platform}/__init__.py | 0 .../sonic_platform/chassis.py | 108 +++++++++++ .../x86_64-cel_e1031-r0/sonic_platform/fan.py | 183 ++++++++++++++++++ .../sonic_platform}/platform.py | 2 +- .../sonic_platform/__init__.py | 0 .../sonic_platform/chassis.py | 109 +++++++++++ .../sonic_platform}/fan.py | 178 +++++------------ .../sonic_platform/platform.py | 23 +++ .../cel-platform-api/setup.py | 29 --- .../sonic_platform_api/chassis.py | 148 -------------- 10 files changed, 472 insertions(+), 308 deletions(-) rename {platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api => device/celestica/x86_64-cel_e1031-r0/sonic_platform}/__init__.py (100%) create mode 100644 device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py create mode 100644 device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py rename {platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api => device/celestica/x86_64-cel_e1031-r0/sonic_platform}/platform.py (92%) create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py rename {platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api => device/celestica/x86_64-cel_seastone-r0/sonic_platform}/fan.py (50%) create mode 100644 device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py delete mode 100644 platform/broadcom/sonic-platform-modules-cel/cel-platform-api/setup.py delete mode 100644 platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/chassis.py diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/__init__.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/__init__.py rename to device/celestica/x86_64-cel_e1031-r0/sonic_platform/__init__.py diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py new file mode 100644 index 000000000000..33fa88f8e700 --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/chassis.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import re +import os +import subprocess +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.fan import Fan +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 + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + self.config_data = {} + for index in range(0, NUM_FAN): + fan = Fan(index) + self._fan_list.append(fan) + 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() + + def __read_config_db(self): + try: + with open(CONFIG_DB_PATH, 'r') as fd: + data = json.load(fd) + return data + except IOError: + raise IOError("Unable to open config_db file !") + + 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' + """ + try: + self.config_data = self.__read_config_db() + base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] + return str(base_mac) + except KeyError: + raise KeyError("Base MAC not found") + + def get_component_versions(self): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Returns: + A string containing platform-specific component versions + """ + + 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 + + component_versions["CPLD"] = cpld_version + component_versions["BIOS"] = bios_version.strip() + return str(component_versions) diff --git a/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py new file mode 100644 index 000000000000..d16290aa4596 --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/fan.py @@ -0,0 +1,183 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the fan status which are available in the platform +# +############################################################################# + +import json +import math +import os.path + +try: + from sonic_platform_base.fan_base import FanBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +EMC2305_FAN_PATH = "/sys/bus/i2c/drivers/emc2305/" +FAN_PATH = "/sys/devices/platform/e1031.smc/" +SYS_GPIO_DIR = "/sys/class/gpio" +EMC2305_MAX_PWM = 255 +EMC2305_FAN_PWM = "pwm{}" +EMC2305_FAN_TARGET = "fan{}_target" +EMC2305_FAN_INPUT = "pwm{}" + + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_index): + self.index = fan_index + self.config_data = {} + self.fan_speed = 0 + + # e1031 fan attributes + # Single emc2305 chip located at i2c-23-4d + # to control a fan module + self.e1031_emc2305_chip = [ + { + 'device': "23-004d", + 'index_map': [1, 2, 4] + } + ] + + # TODO: Add fan presence status in sysfs + self.fan_e1031_presence = "fan{}_prs" + self.fan_e1031_direction = "fan{}_dir" + self.fan_e1031_led = "fan{}_led" + self.fan_e1031_led_col_map = { + self.STATUS_LED_COLOR_GREEN: "green", + self.STATUS_LED_COLOR_RED: "amber", + self.STATUS_LED_COLOR_OFF: "off" + } + FanBase.__init__(self) + + def get_direction(self): + + direction = self.FAN_DIRECTION_INTAKE + + try: + fan_direction_file = (FAN_PATH + + self.fan_e1031_direction.format(self.index+1)) + with open(fan_direction_file, 'r') as file: + raw = file.read().strip('\r\n') + if str(raw).upper() == "F2B": + direction = self.FAN_DIRECTION_INTAKE + else: + direction = self.FAN_DIRECTION_EXHAUST + except IOError: + return False + + return direction + + def get_speed(self): + """ + E1031 platform specific data: + + speed = pwm_in/255*100 + """ + # TODO: Seperate PSU's fan and main fan class + if self.fan_speed != 0: + return self.fan_speed + else: + speed = 0 + pwm = [] + emc2305_chips = self.e1031_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_FAN_PATH, device, EMC2305_FAN_INPUT) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'r') as file: + raw = file.read().strip('\r\n') + pwm.append(int(raw, 10)) + except IOError: + raise IOError("Unable to open " + sysfs_path) + + speed = math.ceil( + float(pwm[0]) * 100 / EMC2305_MAX_PWM) + + return int(speed) + + def get_target_speed(self): + """ + E1031 platform specific data: + + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + + """ + target = 0 + pwm = [] + emc2305_chips = self.e1031_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_FAN_PATH, device, EMC2305_FAN_TARGET) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'r') as file: + raw = file.read().strip('\r\n') + pwm.append(int(raw, 10)) + except IOError: + raise IOError("Unable to open " + sysfs_path) + + target = pwm[0] * 100 / EMC2305_MAX_PWM + + return target + + 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 + """ + return 10 + + def set_speed(self, speed): + """ + Depends on pwm or target mode is selected: + 1) pwm = speed_pc * 255 <-- Currently use this mode. + 2) target_pwm = speed_pc * 100 / 255 + 2.1) set pwm{}_enable to 3 + + """ + pwm = speed * 255 / 100 + emc2305_chips = self.e1031_emc2305_chip + + for chip in emc2305_chips: + device = chip['device'] + fan_index = chip['index_map'] + sysfs_path = "%s%s/%s" % ( + EMC2305_FAN_PATH, device, EMC2305_FAN_PWM) + sysfs_path = sysfs_path.format(fan_index[self.index]) + try: + with open(sysfs_path, 'w') as file: + file.write(str(int(pwm))) + except IOError: + return False + + return True + + def set_status_led(self, color): + + try: + fan_led_file = (FAN_PATH + + self.fan_e1031_led.format(self.index+1)) + with open(fan_led_file, 'r') as file: + file.write(self.fan_e1031_led_col_map[color]) + except IOError: + return False + + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/platform.py b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py similarity index 92% rename from platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/platform.py rename to device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py index 9b5d780e42c4..a632de87e742 100644 --- a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/platform.py +++ b/device/celestica/x86_64-cel_e1031-r0/sonic_platform/platform.py @@ -10,7 +10,7 @@ try: from sonic_platform_base.platform_base import PlatformBase - from sonic_platform_api.chassis import Chassis + from sonic_platform.chassis import Chassis except ImportError as e: raise ImportError(str(e) + "- required module not found") diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py new file mode 100644 index 000000000000..1d2e9af3757b --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/chassis.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +import sys +import re +import os +import subprocess +import json + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform.fan import Fan +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 +CPLD_ADDR_MAPPING = { + "CPLD1": "0x100", + "CPLD2": "0x200", + "CPLD3": "0x280", + "CPLD4": "0x300", + "CPLD5": "0x380" +} + + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + def __init__(self): + self.config_data = {} + for index in range(0, NUM_FAN): + fan = Fan(index) + self._fan_list.append(fan) + 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() + + def __read_config_db(self): + try: + with open(CONFIG_DB_PATH, 'r') as fd: + data = json.load(fd) + return data + except IOError: + raise IOError("Unable to open config_db file !") + + 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' + """ + try: + self.config_data = self.__read_config_db() + base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] + return str(base_mac) + except KeyError: + raise KeyError("Base MAC not found") + + def get_component_versions(self): + """ + Retrieves platform-specific hardware/firmware versions for chassis + componenets such as BIOS, CPLD, FPGA, etc. + Returns: + A string containing platform-specific component versions + """ + + 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() + 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) diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/fan.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py similarity index 50% rename from platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/fan.py rename to device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py index 796c2e1cdae1..227c1d2ade52 100644 --- a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/fan.py +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/fan.py @@ -17,23 +17,23 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") +CONFIG_DB_PATH = "/etc/sonic/config_db.json" +EMC2305_PATH = "/sys/bus/i2c/drivers/emc2305/" +SYS_GPIO_DIR = "/sys/class/gpio" +EMC2305_MAX_PWM = 255 +EMC2305_FAN_PWM = "pwm{}" +EMC2305_FAN_TARGET = "fan{}_target" +EMC2305_FAN_INPUT = "pwm{}" + class Fan(FanBase): """Platform-specific Fan class""" def __init__(self, fan_index): - FanBase.__init__(self) self.index = fan_index self.config_data = {} - self.config_db_path = "/etc/sonic/config_db.json" - self.platform = self.get_platform() self.fan_speed = 0 - self.fan_emc2305_path = "/sys/bus/i2c/drivers/emc2305/" - self.sys_gpio_dir = "/sys/class/gpio" - self.fan_em2305_max_pwm = 255 - self.fan_emc2305_pwm = "pwm{}" - self.fan_emc2305_target = "fan{}_target" - self.fan_emc2305_input = "pwm{}" + FanBase.__init__(self) # dx010 fan attributes # Two EMC2305s located at i2c-13-4d and i2c-13-2e @@ -58,44 +58,8 @@ def __init__(self, fan_index): {'prs': 14, 'dir': 19, 'color': {'red': 33, 'green': 34}}, ] - # e1031 fan attributes - # Single emc2305 chip located at i2c-23-4d - # to control a fan module - self.e1031_emc2305_chip = [ - { - 'device': "23-004d", - 'index_map': [1, 2, 4] - } - ] - self.fan_e1031_path = "/sys/devices/platform/e1031.smc/" - # TODO: Add fan presence status in sysfs - self.fan_e1031_presence = "fan{}_prs" - self.fan_e1031_direction = "fan{}_dir" - self.fan_e1031_led = "fan{}_led" - self.fan_e1031_led_col_map = { - self.STATUS_LED_COLOR_GREEN: "green", - self.STATUS_LED_COLOR_RED: "amber", - self.STATUS_LED_COLOR_OFF: "off" - } - - def __read_config_db(self): - try: - with open(self.config_db_path, 'r') as fd: - data = json.load(fd) - return data - except IOError: - raise IOError("Unable to open config_db file !") - - def get_platform(self): - try: - self.config_data = self.__read_config_db() - platform = self.config_data["DEVICE_METADATA"]["localhost"]["platform"] - return platform - except KeyError: - raise KeyError("Platform name not found") - def get_gpio_base(self): - for r in os.listdir(self.sys_gpio_dir): + for r in os.listdir(SYS_GPIO_DIR): if "gpiochip" in r: return int(r[8:], 10) return 216 # Reserve @@ -103,7 +67,7 @@ def get_gpio_base(self): def get_gpio_value(self, pinnum): gpio_base = self.dx010_fan_gpio[0]['base'] - gpio_dir = self.sys_gpio_dir + '/gpio' + str(gpio_base+pinnum) + gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" try: @@ -118,7 +82,7 @@ def get_gpio_value(self, pinnum): def set_gpio_value(self, pinnum, value=0): gpio_base = self.dx010_fan_gpio[0]['base'] - gpio_dir = self.sys_gpio_dir + '/gpio' + str(gpio_base+pinnum) + gpio_dir = SYS_GPIO_DIR + '/gpio' + str(gpio_base+pinnum) gpio_file = gpio_dir + "/value" try: @@ -130,32 +94,18 @@ def set_gpio_value(self, pinnum, value=0): def get_direction(self): direction = self.FAN_DIRECTION_INTAKE + raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['dir']) - if self.platform == "x86_64-cel_seastone-r0": - raw = self.get_gpio_value(self.dx010_fan_gpio[self.index+1]['dir']) - if int(raw, 10) == 0: - direction = self.FAN_DIRECTION_INTAKE - else: - direction = self.FAN_DIRECTION_EXHAUST - - elif self.platform == "x86_64-cel_e1031-r0": - try: - fan_direction_file = (self.fan_e1031_path + - self.fan_e1031_direction.format(self.index+1)) - with open(fan_direction_file, 'r') as file: - raw = file.read().strip('\r\n') - if str(raw).upper() == "F2B": - direction = self.FAN_DIRECTION_INTAKE - else: - direction = self.FAN_DIRECTION_EXHAUST - except IOError: - return False + if int(raw, 10) == 0: + direction = self.FAN_DIRECTION_INTAKE + else: + direction = self.FAN_DIRECTION_EXHAUST return direction def get_speed(self): """ - DX010 and E1031 platform specific data: + DX010 platform specific data: speed = pwm_in/255*100 """ @@ -165,20 +115,13 @@ def get_speed(self): else: speed = 0 pwm = [] - emc2305_chips = {} - - if self.platform == "x86_64-cel_seastone-r0": - emc2305_chips = self.dx010_emc2305_chip - elif self.platform == "x86_64-cel_e1031-r0": - emc2305_chips = self.e1031_emc2305_chip - else: - return 0 + emc2305_chips = self.dx010_emc2305_chip for chip in emc2305_chips: device = chip['device'] fan_index = chip['index_map'] sysfs_path = "%s%s/%s" % ( - self.fan_emc2305_path, device, self.fan_emc2305_input) + EMC2305_PATH, device, EMC2305_FAN_INPUT) sysfs_path = sysfs_path.format(fan_index[self.index]) try: with open(sysfs_path, 'r') as file: @@ -188,13 +131,13 @@ def get_speed(self): raise IOError("Unable to open " + sysfs_path) speed = math.ceil( - float(pwm[0]) * 100 / self.fan_em2305_max_pwm) + float(pwm[0]) * 100 / EMC2305_MAX_PWM) return int(speed) def get_target_speed(self): """ - DX010 and E1031 platform specific data: + DX010 platform specific data: speed_pc = pwm_target/255*100 @@ -204,20 +147,13 @@ def get_target_speed(self): """ target = 0 pwm = [] - emc2305_chips = {} - - if self.platform == "x86_64-cel_seastone-r0": - emc2305_chips = self.dx010_emc2305_chip - elif self.platform == "x86_64-cel_e1031-r0": - emc2305_chips = self.e1031_emc2305_chip - else: - return target + emc2305_chips = self.dx010_emc2305_chip for chip in emc2305_chips: device = chip['device'] fan_index = chip['index_map'] sysfs_path = "%s%s/%s" % ( - self.fan_emc2305_path, device, self.fan_emc2305_target) + EMC2305_PATH, device, EMC2305_FAN_TARGET) sysfs_path = sysfs_path.format(fan_index[self.index]) try: with open(sysfs_path, 'r') as file: @@ -226,7 +162,7 @@ def get_target_speed(self): except IOError: raise IOError("Unable to open " + sysfs_path) - target = pwm[0] * 100 / self.fan_em2305_max_pwm + target = pwm[0] * 100 / EMC2305_MAX_PWM return target @@ -248,20 +184,13 @@ def set_speed(self, speed): """ pwm = speed * 255 / 100 - emc2305_chips = {} - - if self.platform == "x86_64-cel_seastone-r0": - emc2305_chips = self.dx010_emc2305_chip - elif self.platform == "x86_64-cel_e1031-r0": - emc2305_chips = self.e1031_emc2305_chip - else: - return False + emc2305_chips = self.dx010_emc2305_chip for chip in emc2305_chips: device = chip['device'] fan_index = chip['index_map'] sysfs_path = "%s%s/%s" % ( - self.fan_emc2305_path, device, self.fan_emc2305_pwm) + EMC2305_PATH, device, EMC2305_FAN_PWM) sysfs_path = sysfs_path.format(fan_index[self.index]) try: with open(sysfs_path, 'w') as file: @@ -272,39 +201,28 @@ def set_speed(self, speed): return True def set_status_led(self, color): - - if self.platform == "x86_64-cel_seastone-r0": - try: - if color == self.STATUS_LED_COLOR_GREEN: - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['red'], 1) - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['green'], 0) - - elif color == self.STATUS_LED_COLOR_RED: - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['red'], 0) - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['green'], 1) - - elif color == self.STATUS_LED_COLOR_OFF: - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['red'], 1) - self.set_gpio_value( - self.dx010_fan_gpio[self.index+1]['color']['green'], 1) - else: - return False - - except IOError: + try: + if color == self.STATUS_LED_COLOR_GREEN: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 1) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 0) + + elif color == self.STATUS_LED_COLOR_RED: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 0) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 1) + + elif color == self.STATUS_LED_COLOR_OFF: + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['red'], 1) + self.set_gpio_value( + self.dx010_fan_gpio[self.index+1]['color']['green'], 1) + else: return False - elif self.platform == "x86_64-cel_e1031-r0": - try: - fan_led_file = (self.fan_e1031_path + - self.fan_e1031_led.format(self.index+1)) - with open(fan_led_file, 'r') as file: - file.write(self.fan_e1031_led_col_map[color]) - except IOError: - return False + except IOError: + return False return True diff --git a/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py new file mode 100644 index 000000000000..a632de87e742 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/sonic_platform/platform.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the platform information +# +############################################################################# + +try: + from sonic_platform_base.platform_base import PlatformBase + from sonic_platform.chassis import Chassis +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class Platform(PlatformBase): + """Platform-specific Platform class""" + + def __init__(self): + PlatformBase.__init__(self) + self._chassis = Chassis() diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/setup.py b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/setup.py deleted file mode 100644 index 29a63e0cb7da..000000000000 --- a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -from setuptools import setup - -setup( - name='cel-platform-api', - version='0.1', - description='SONiC platform management API implementation for Celestica platform', - license='Apache 2.0', - author='SONiC Team', - author_email='linuxnetdev@microsoft.com', - url='https://github.com/Azure/sonic-buildimage', - maintainer='Wirut Getbamrung', - maintainer_email='wgetbumr@celestica.com', - packages=[ - 'sonic_platform_api', - ], - classifiers=[ - 'Development Status :: 3 - Alpha', - 'Environment :: Plugins', - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - 'Intended Audience :: System Administrators', - 'License :: OSI Approved :: Apache Software License', - 'Natural Language :: English', - 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 2.7', - 'Topic :: Utilities', - ], - keywords='sonic SONiC platform-api PLATFORM-API', -) diff --git a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/chassis.py b/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/chassis.py deleted file mode 100644 index afc49abc61aa..000000000000 --- a/platform/broadcom/sonic-platform-modules-cel/cel-platform-api/sonic_platform_api/chassis.py +++ /dev/null @@ -1,148 +0,0 @@ -#!/usr/bin/env python - -############################################################################# -# Celestica -# -# Module contains an implementation of SONiC Platform Base API and -# provides the Chassis information which are available in the platform -# -############################################################################# - -import sys -import re -import os -import subprocess -import json - -try: - from sonic_platform_base.chassis_base import ChassisBase - from sonic_platform_api.fan import Fan -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -class Chassis(ChassisBase): - """Platform-specific Chassis class""" - - def __init__(self): - ChassisBase.__init__(self) - self.config_data = {} - self.config_db_path = "/etc/sonic/config_db.json" - self.platform = self.get_platform() - NUM_FAN = { - "x86_64-cel_e1031-r0": 3, - "x86_64-cel_seastone-r0": 5 - }.get(self.platform, 0) - for index in range(0, NUM_FAN): - fan = Fan(index) - self._fan_list.append(fan) - self.bios_version_path = "/sys/class/dmi/id/bios_version" - self.smc_cpld_e1031_path = "/sys/devices/platform/e1031.smc/version" - self.mmc_cpld_e1031_path = "/sys/devices/platform/e1031.smc/getreg" - self.cpld_dx010_path = "/sys/devices/platform/dx010_cpld/getreg" - - 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() - - def __read_config_db(self): - try: - with open(self.config_db_path, 'r') as fd: - data = json.load(fd) - return data - except IOError: - raise IOError("Unable to open config_db file !") - - def get_platform(self): - try: - self.config_data = self.__read_config_db() - platform = self.config_data["DEVICE_METADATA"]["localhost"]["platform"] - return platform - except KeyError: - raise KeyError("Platform name not found") - - 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' - """ - try: - self.config_data = self.__read_config_db() - base_mac = self.config_data["DEVICE_METADATA"]["localhost"]["mac"] - return str(base_mac) - except KeyError: - raise KeyError("Base MAC not found") - - def get_component_versions(self): - """ - Retrieves platform-specific hardware/firmware versions for chassis - componenets such as BIOS, CPLD, FPGA, etc. - Returns: - A string containing platform-specific component versions - """ - - component_versions = dict() - - # Get BIOS version - try: - with open(self.bios_version_path, 'r') as fd: - bios_version = fd.read() - except IOError: - raise IOError("Unable to open version file !") - - # Get CPLD version - if self.platform == "x86_64-cel_seastone-r0": - - CPLD_1 = self.__get_register_value(self.cpld_dx010_path, '0x100') - CPLD_2 = self.__get_register_value(self.cpld_dx010_path, '0x200') - CPLD_3 = self.__get_register_value(self.cpld_dx010_path, '0x280') - CPLD_4 = self.__get_register_value(self.cpld_dx010_path, '0x300') - CPLD_5 = self.__get_register_value(self.cpld_dx010_path, '0x380') - - CPLD_1 = 'None' if CPLD_1 is 'None' else "{}.{}".format( - int(CPLD_1[2], 16), int(CPLD_1[3], 16)) - CPLD_2 = 'None' if CPLD_2 is 'None' else "{}.{}".format( - int(CPLD_2[2], 16), int(CPLD_2[3], 16)) - CPLD_3 = 'None' if CPLD_3 is 'None' else "{}.{}".format( - int(CPLD_3[2], 16), int(CPLD_3[3], 16)) - CPLD_4 = 'None' if CPLD_4 is 'None' else "{}.{}".format( - int(CPLD_4[2], 16), int(CPLD_4[3], 16)) - CPLD_5 = 'None' if CPLD_5 is 'None' else "{}.{}".format( - int(CPLD_5[2], 16), int(CPLD_5[3], 16)) - - cpld_version = dict() - cpld_version["CPLD1"] = CPLD_1 - cpld_version["CPLD2"] = CPLD_2 - cpld_version["CPLD3"] = CPLD_3 - cpld_version["CPLD4"] = CPLD_4 - cpld_version["CPLD5"] = CPLD_5 - component_versions["CPLD"] = cpld_version - - elif self.platform == "x86_64-cel_e1031-r0": - cpld_version = dict() - - with open(self.smc_cpld_e1031_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( - self.mmc_cpld_e1031_path, '0x100') - 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 - - component_versions["CPLD"] = cpld_version - - component_versions["BIOS"] = bios_version.strip() - return str(component_versions) From 97834d0995ead342a62246902292f95adf445118 Mon Sep 17 00:00:00 2001 From: Wirut Getbamrung Date: Tue, 23 Apr 2019 14:56:57 +0700 Subject: [PATCH 3/3] [platform/cel] Remove rule to build platform api python wheel --- platform/broadcom/platform-modules-cel.mk | 8 -------- 1 file changed, 8 deletions(-) diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index 0535c6b3ee9d..1224faaa6750 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -17,11 +17,3 @@ $(CEL_HALIBURTON_PLATFORM_MODULE)_PLATFORM = x86_64-cel_e1031-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_HALIBURTON_PLATFORM_MODULE))) SONIC_STRETCH_DEBS += $(CEL_DX010_PLATFORM_MODULE) - -# Celestica platform api package -SONIC_PLATFORM_API_CEL_VERSION = 0.1 - -SONIC_PLATFORM_API_PY2 = cel_platform_api-$(SONIC_PLATFORM_API_CEL_VERSION)-py2-none-any.whl -$(SONIC_PLATFORM_API_PY2)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cel/cel-platform-api -$(SONIC_PLATFORM_API_PY2)_PYTHON_VERSION = 2 -SONIC_PYTHON_WHEELS += $(SONIC_PLATFORM_API_PY2)