diff --git a/device/celestica/x86_64-cel_e1031-r0/plugins/fwutil.py b/device/celestica/x86_64-cel_e1031-r0/plugins/fwutil.py new file mode 100644 index 000000000000..5942170e0f7e --- /dev/null +++ b/device/celestica/x86_64-cel_e1031-r0/plugins/fwutil.py @@ -0,0 +1,129 @@ +#!/usr/bin/env python + +import os.path +import subprocess +import click +import os + +try: + from sonic_fw.fw_manage_base import FwBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FwUtil(FwBase): + """Platform-specific FwUtil class""" + + SUPPORTED_MODULES = ["BIOS", "CPLD"] + BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" + SMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/version" + MMC_CPLD_PATH = "/sys/devices/platform/e1031.smc/getreg" + MMC_CPLD_ADDR = '0x100' + + # Run bash command and print output to stdout + def run_command(self, command): + click.echo(click.style("Command: ", fg='cyan') + + click.style(command, fg='green')) + + proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + (out, err) = proc.communicate() + click.echo("") + click.echo(out) + + if proc.returncode != 0: + return False + return True + + # Read register and return value + 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 + return raw_data.strip() + + # Get BIOS firmware version + def get_bios_version(self): + try: + with open(self.BIOS_VERSION_PATH, 'r') as fd: + bios_version = fd.read() + return bios_version.strip() + except Exception, e: + return None + + # Get CPLD firmware version + def get_cpld_version(self): + try: + with open(self.SMC_CPLD_PATH, 'r') as fd: + smc_cpld_version = fd.read() + + smc_cpld_version = "{}.{}".format(int(smc_cpld_version[2], 16), int( + smc_cpld_version[3], 16)) if smc_cpld_version is not None else smc_cpld_version + + mmc_cpld_version = self.__get_register_value( + self.MMC_CPLD_PATH, self.MMC_CPLD_ADDR) + mmc_cpld_version = "{}.{}".format(int(mmc_cpld_version[2], 16), int( + mmc_cpld_version[3], 16)) if mmc_cpld_version is not None else mmc_cpld_version + + cpld_version = dict() + cpld_version["SMC"] = str(smc_cpld_version) + cpld_version["MMC"] = str(mmc_cpld_version) + + return cpld_version + except Exception, e: + return None + + def get_module_list(self): + """ + Retrieves the list of module that available on the device + + :return: A list of modules + """ + return self.SUPPORTED_MODULES + + def get_fw_version(self, module_name): + """ + Retrieves the firmware version of module + + :param module_name: A string, module name + :return: Dict, firmware version object + """ + + fw_version = { + "BIOS": self.get_bios_version(), + "CPLD": self.get_cpld_version() + }.get(module_name.upper(), None) + + fw_dict = dict() + fw_dict["module_name"] = module_name + fw_dict["fw_version"] = fw_version + fw_dict["has_submodule"] = True if type(fw_version) is dict else False + + return fw_dict + + def install(self, module_name, image_path): + """ + Install firmware to module + + :param module_name: A string, name of module that need to install new firmware + :param image_path: A string, path to firmware image + :return: Boolean + """ + module_name = module_name.upper() + + if module_name == "CPLD": + img_dir = os.path.dirname(image_path) + 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(img_dir, (root.lower() + ext)) + os.rename(image_path, new_image_path) + install_command = "ls" + install_command = "ispvm %s" % new_image_path + elif module_name == "BIOS": + click.echo("Not supported") + return False + + return self.run_command(install_command) diff --git a/device/celestica/x86_64-cel_seastone-r0/plugins/fwutil.py b/device/celestica/x86_64-cel_seastone-r0/plugins/fwutil.py new file mode 100644 index 000000000000..6e9815de83bf --- /dev/null +++ b/device/celestica/x86_64-cel_seastone-r0/plugins/fwutil.py @@ -0,0 +1,127 @@ +#!/usr/bin/env python + +import os.path +import subprocess +import click +import os + +try: + from sonic_fw.fw_manage_base import FwBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FwUtil(FwBase): + """Platform-specific FwUtil class""" + + CPLD_ADDR_MAPPING = { + "CPLD1": "0x100", + "CPLD2": "0x200", + "CPLD3": "0x280", + "CPLD4": "0x300", + "CPLD5": "0x380" + } + SUPPORTED_MODULES = ["BIOS", "CPLD"] + GETREG_PATH = "/sys/devices/platform/dx010_cpld/getreg" + BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" + + # Run bash command and print output to stdout + def run_command(self, command): + click.echo(click.style("Command: ", fg='cyan') + + click.style(command, fg='green')) + + proc = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE) + (out, err) = proc.communicate() + click.echo("") + click.echo(out) + + if proc.returncode != 0: + return False + return True + + # Read register and return value + 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 + return raw_data.strip() + + # Get BIOS firmware version + def get_bios_version(self): + try: + with open(self.BIOS_VERSION_PATH, 'r') as fd: + bios_version = fd.read() + return bios_version.strip() + except Exception, e: + return None + + # Get CPLD firmware version + def get_cpld_version(self): + cpld_version = dict() + for cpld_name in self.CPLD_ADDR_MAPPING: + try: + cpld_addr = self.CPLD_ADDR_MAPPING[cpld_name] + cpld_version_raw = self.__get_register_value( + self.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' + return cpld_version + + def get_module_list(self): + """ + Retrieves the list of module that available on the device + + :return: A list of modules + """ + return self.SUPPORTED_MODULES + + def get_fw_version(self, module_name): + """ + Retrieves the firmware version of module + + :param module_name: A string, module name + :return: Dict, firmware version object + """ + + fw_version = { + "BIOS": self.get_bios_version(), + "CPLD": self.get_cpld_version() + }.get(module_name.upper(), None) + + fw_dict = dict() + fw_dict["module_name"] = module_name + fw_dict["fw_version"] = fw_version + fw_dict["has_submodule"] = True if type(fw_version) is dict else False + + return fw_dict + + def install(self, module_name, image_path): + """ + Install firmware to module + + :param module_name: A string, name of module that need to install new firmware + :param image_path: A string, path to firmware image + :return: Boolean + """ + module_name = module_name.upper() + + if module_name == "CPLD": + img_dir = os.path.dirname(image_path) + 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(img_dir, (root.lower() + ext)) + os.rename(image_path, new_image_path) + install_command = "ls" + install_command = "ispvm %s" % new_image_path + elif module_name == "BIOS": + click.echo("Not supported") + return False + + return self.run_command(install_command) 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..5e55b1190128 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)) {