From f70bda918f62236e6a062a4032e16adec0cf2489 Mon Sep 17 00:00:00 2001 From: Fei Zhou Date: Fri, 31 May 2024 09:26:08 -0400 Subject: [PATCH] [H3]Fix port status down issue, fan speed setting, use CPLD watchdog and other minor changes --- .../sonic-platform-nokia-ixr7220h3.postinst | 41 +---- ixr7220h3/modules/nokia_7220_h3_cpupld.c | 60 ++----- ixr7220h3/modules/nokia_7220_h3_swpld1.c | 10 +- ixr7220h3/modules/nokia_7220_h3_swpld2.c | 140 +++++++++++++++-- ixr7220h3/modules/nokia_7220_h3_swpld3.c | 138 ++++++++++++++-- ixr7220h3/scripts/ixr7220h3_platform_init.sh | 16 +- ixr7220h3/sonic_platform/chassis.py | 64 ++++---- ixr7220h3/sonic_platform/component.py | 41 ++--- ixr7220h3/sonic_platform/fan.py | 68 +++++--- ixr7220h3/sonic_platform/fan_drawer.py | 123 +++++++++++++-- ixr7220h3/sonic_platform/platform.py | 3 +- ixr7220h3/sonic_platform/psu.py | 24 +++ ixr7220h3/sonic_platform/sfp.py | 90 ++++++----- ixr7220h3/sonic_platform/sfp_event.py | 76 ++++++--- ixr7220h3/sonic_platform/thermal.py | 1 + ixr7220h3/sonic_platform/watchdog.py | 148 +++++++++--------- 16 files changed, 709 insertions(+), 334 deletions(-) diff --git a/debian/sonic-platform-nokia-ixr7220h3.postinst b/debian/sonic-platform-nokia-ixr7220h3.postinst index aa47471..e7de55e 100644 --- a/debian/sonic-platform-nokia-ixr7220h3.postinst +++ b/debian/sonic-platform-nokia-ixr7220h3.postinst @@ -3,41 +3,6 @@ # # see: dh_installdeb(1) -set -e - -# summary of how this script can be called: -# * `configure' -# * `abort-upgrade' -# * `abort-remove' `in-favour' -# -# * `abort-remove' -# * `abort-deconfigure' `in-favour' -# `removing' -# -# for details, see https://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - configure) - chmod a+x /usr/local/bin/ixr7220h3_platform_init.sh - systemctl enable ixr7220h3_platform_init.service - systemctl start ixr7220h3_platform_init.service - - ;; - - abort-upgrade|abort-remove|abort-deconfigure) - ;; - - *) - echo "postinst called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 \ No newline at end of file +chmod a+x /usr/local/bin/ixr7220h3_platform_init.sh +systemctl enable ixr7220h3_platform_init.service +systemctl start ixr7220h3_platform_init.service \ No newline at end of file diff --git a/ixr7220h3/modules/nokia_7220_h3_cpupld.c b/ixr7220h3/modules/nokia_7220_h3_cpupld.c index 15cfd16..3be8516 100644 --- a/ixr7220h3/modules/nokia_7220_h3_cpupld.c +++ b/ixr7220h3/modules/nokia_7220_h3_cpupld.c @@ -37,9 +37,6 @@ #define CPU_CPLD_UPGRADE_REG 0x0B // REG BIT FIELD POSITION or MASK -#define SYS_CPLD_REV_REG_MNR_MSK 0xF -#define SYS_CPLD_REV_REG_MJR 0x4 - #define BOARD_REV_TYPE_REG_TYPE_MSK 0xF #define BOARD_REV_TYPE_REG_REV 0x4 @@ -47,13 +44,6 @@ #define WATCHDOG_REG_WD_EN 0x3 #define WATCHDOG_REG_WD_TIMER 0x4 -#define CPU_SYS_RST_REG_CPU_PWR_ERR 0x0 -#define CPU_SYS_RST_REG_BOOT_FAIL 0x2 -#define CPU_SYS_RST_REG_BIOS_SWITCHOVER 0x3 -#define CPU_SYS_RST_REG_WD_FAIL 0x4 -#define CPU_SYS_RST_REG_WARM_RST 0x6 -#define CPU_SYS_RST_REG_COLD_RST 0x7 - #define POWER_STATUS_REG_V1P35 0x0 #define POWER_STATUS_REG_V1P8 0x1 #define POWER_STATUS_REG_V3P3 0x2 @@ -68,10 +58,10 @@ static const unsigned short cpld_address_list[] = {0x31, I2C_CLIENT_END}; struct cpld_data { struct i2c_client *client; struct mutex update_lock; - int cpld_major_version; - int cpld_minor_version; + int code_ver; int board_revision; int board_type; + int cpu_sys_rst; }; static int nokia_7220_h3_cpupld_read(struct cpld_data *data, u8 reg) @@ -102,16 +92,10 @@ static void nokia_7220_h3_cpupld_write(struct cpld_data *data, u8 reg, u8 value) mutex_unlock(&data->update_lock); } -static ssize_t show_cpld_major_version(struct device *dev, struct device_attribute *devattr, char *buf) -{ - struct cpld_data *data = dev_get_drvdata(dev); - return sprintf(buf, "0x%02x\n", data->cpld_major_version); -} - -static ssize_t show_cpld_minor_version(struct device *dev, struct device_attribute *devattr, char *buf) +static ssize_t show_code_ver(struct device *dev, struct device_attribute *devattr, char *buf) { struct cpld_data *data = dev_get_drvdata(dev); - return sprintf(buf, "0x%02x\n", data->cpld_minor_version); + return sprintf(buf, "0x%02x\n", data->code_ver); } static ssize_t show_board_revision(struct device *dev, struct device_attribute *devattr, char *buf) @@ -133,7 +117,7 @@ static ssize_t show_board_revision(struct device *dev, struct device_attribute * revision = "X03"; break; default: - revision = "RSVD"; + revision = "RESERVED"; break; } @@ -284,11 +268,7 @@ static ssize_t set_watchdog(struct device *dev, struct device_attribute *devattr static ssize_t show_sys_rst_cause(struct device *dev, struct device_attribute *devattr, char *buf) { struct cpld_data *data = dev_get_drvdata(dev); - struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); - u8 val = 0; - val = nokia_7220_h3_cpupld_read(data, CPU_SYS_RST_REG); - - return sprintf(buf, "%d\n", (val>>sda->index) & 0x1 ? 1:0); + return sprintf(buf, "%02x\n", data->cpu_sys_rst); } static ssize_t show_cpu_pwr_status(struct device *dev, struct device_attribute *devattr, char *buf) @@ -337,20 +317,14 @@ static ssize_t set_cpu_cpld_upgrade(struct device *dev, struct device_attribute } // sysfs attributes -static SENSOR_DEVICE_ATTR(cpld_major_version, S_IRUGO, show_cpld_major_version, NULL, 0); -static SENSOR_DEVICE_ATTR(cpld_minor_version, S_IRUGO, show_cpld_minor_version, NULL, SYS_CPLD_REV_REG_MJR); +static SENSOR_DEVICE_ATTR(code_ver, S_IRUGO, show_code_ver, NULL, 0); static SENSOR_DEVICE_ATTR(board_revision, S_IRUGO, show_board_revision, NULL, 0); static SENSOR_DEVICE_ATTR(board_type, S_IRUGO, show_board_type, NULL, BOARD_REV_TYPE_REG_REV); static SENSOR_DEVICE_ATTR(scratch, S_IRUGO | S_IWUSR, show_scratch, set_scratch, 0); static SENSOR_DEVICE_ATTR(wd_punch, S_IRUGO | S_IWUSR, show_watchdog, set_watchdog, WATCHDOG_REG_WD_PUNCH); static SENSOR_DEVICE_ATTR(wd_enable, S_IRUGO | S_IWUSR, show_watchdog, set_watchdog, WATCHDOG_REG_WD_EN); static SENSOR_DEVICE_ATTR(wd_timer, S_IRUGO | S_IWUSR, show_watchdog, set_watchdog, WATCHDOG_REG_WD_TIMER); -static SENSOR_DEVICE_ATTR(cpu_pwr_err, S_IRUGO, show_sys_rst_cause, NULL, CPU_SYS_RST_REG_CPU_PWR_ERR); -static SENSOR_DEVICE_ATTR(boot_fail, S_IRUGO, show_sys_rst_cause, NULL, CPU_SYS_RST_REG_BOOT_FAIL); -static SENSOR_DEVICE_ATTR(bios_switchover, S_IRUGO, show_sys_rst_cause, NULL, CPU_SYS_RST_REG_BIOS_SWITCHOVER); -static SENSOR_DEVICE_ATTR(wd_reset, S_IRUGO, show_sys_rst_cause, NULL, CPU_SYS_RST_REG_WD_FAIL); -static SENSOR_DEVICE_ATTR(warm_reset, S_IRUGO, show_sys_rst_cause, NULL, CPU_SYS_RST_REG_WARM_RST); -static SENSOR_DEVICE_ATTR(cold_reset, S_IRUGO, show_sys_rst_cause, NULL, CPU_SYS_RST_REG_COLD_RST); +static SENSOR_DEVICE_ATTR(cpu_sys_rst, S_IRUGO, show_sys_rst_cause, NULL, 0); static SENSOR_DEVICE_ATTR(cpu_pwr_1v35, S_IRUGO, show_cpu_pwr_status, NULL, POWER_STATUS_REG_V1P35); static SENSOR_DEVICE_ATTR(cpu_pwr_1v8, S_IRUGO, show_cpu_pwr_status, NULL, POWER_STATUS_REG_V1P8); static SENSOR_DEVICE_ATTR(cpu_pwr_3v3, S_IRUGO, show_cpu_pwr_status, NULL, POWER_STATUS_REG_V3P3); @@ -362,20 +336,14 @@ static SENSOR_DEVICE_ATTR(cpu_pwr_1v5, S_IRUGO, show_cpu_pwr_status, NULL, POWER static SENSOR_DEVICE_ATTR(cpu_cpld_upgrade, S_IRUGO | S_IWUSR, show_cpu_cpld_upgrade, set_cpu_cpld_upgrade, 0); static struct attribute *nokia_7220_h3_cpupld_attributes[] = { - &sensor_dev_attr_cpld_major_version.dev_attr.attr, - &sensor_dev_attr_cpld_minor_version.dev_attr.attr, + &sensor_dev_attr_code_ver.dev_attr.attr, &sensor_dev_attr_board_revision.dev_attr.attr, &sensor_dev_attr_board_type.dev_attr.attr, &sensor_dev_attr_scratch.dev_attr.attr, &sensor_dev_attr_wd_punch.dev_attr.attr, &sensor_dev_attr_wd_enable.dev_attr.attr, &sensor_dev_attr_wd_timer.dev_attr.attr, - &sensor_dev_attr_cpu_pwr_err.dev_attr.attr, - &sensor_dev_attr_boot_fail.dev_attr.attr, - &sensor_dev_attr_bios_switchover.dev_attr.attr, - &sensor_dev_attr_wd_reset.dev_attr.attr, - &sensor_dev_attr_warm_reset.dev_attr.attr, - &sensor_dev_attr_cold_reset.dev_attr.attr, + &sensor_dev_attr_cpu_sys_rst.dev_attr.attr, &sensor_dev_attr_cpu_pwr_1v35.dev_attr.attr, &sensor_dev_attr_cpu_pwr_1v8.dev_attr.attr, &sensor_dev_attr_cpu_pwr_3v3.dev_attr.attr, @@ -422,10 +390,10 @@ static int nokia_7220_h3_cpupld_probe(struct i2c_client *client) goto exit; } - data->cpld_major_version = nokia_7220_h3_cpupld_read(data, SYS_CPLD_REV_REG) & SYS_CPLD_REV_REG_MNR_MSK; - data->cpld_minor_version = nokia_7220_h3_cpupld_read(data, SYS_CPLD_REV_REG) >> SYS_CPLD_REV_REG_MJR; + data->code_ver = nokia_7220_h3_cpupld_read(data, SYS_CPLD_REV_REG); data->board_revision = nokia_7220_h3_cpupld_read(data, BOARD_REV_TYPE_REG) & BOARD_REV_TYPE_REG_TYPE_MSK; - data->board_type = nokia_7220_h3_cpupld_read(data, BOARD_REV_TYPE_REG) >> BOARD_REV_TYPE_REG_REV; + data->board_type = nokia_7220_h3_cpupld_read(data, BOARD_REV_TYPE_REG) >> BOARD_REV_TYPE_REG_REV; + data->cpu_sys_rst = nokia_7220_h3_cpupld_read(data, CPU_SYS_RST_REG); return 0; @@ -481,4 +449,4 @@ MODULE_DESCRIPTION("NOKIA-7220-IXR-H3 CPLD driver"); MODULE_LICENSE("GPL"); module_init(nokia_7220_h3_cpupld_init); -module_exit(nokia_7220_h3_cpupld_exit); +module_exit(nokia_7220_h3_cpupld_exit); \ No newline at end of file diff --git a/ixr7220h3/modules/nokia_7220_h3_swpld1.c b/ixr7220h3/modules/nokia_7220_h3_swpld1.c index 7eefe9a..b383862 100644 --- a/ixr7220h3/modules/nokia_7220_h3_swpld1.c +++ b/ixr7220h3/modules/nokia_7220_h3_swpld1.c @@ -140,7 +140,7 @@ struct cpld_data { int swbd_id; int swbd_version; int cpld_type; - int cpld_version; + int code_ver; }; static int nokia_7220_h3_swpld_read(struct cpld_data *data, u8 reg) @@ -226,7 +226,7 @@ static ssize_t show_cpld_type(struct device *dev, struct device_attribute *devat static ssize_t show_cpld_version(struct device *dev, struct device_attribute *devattr, char *buf) { struct cpld_data *data = dev_get_drvdata(dev); - return sprintf(buf, "0x%02x\n", data->cpld_version); + return sprintf(buf, "0x%02x\n", data->code_ver); } static ssize_t show_scratch(struct device *dev, struct device_attribute *devattr, char *buf) @@ -604,7 +604,7 @@ static ssize_t set_misc_sel_reg(struct device *dev, struct device_attribute *dev static SENSOR_DEVICE_ATTR(swbd_id, S_IRUGO, show_swbd_id, NULL, 0); static SENSOR_DEVICE_ATTR(swbd_version, S_IRUGO, show_swbd_version, NULL, 0); static SENSOR_DEVICE_ATTR(cpld_type, S_IRUGO, show_cpld_type, NULL, SWPLD1_CPLD_REV_REG_TYPE); -static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, show_cpld_version, NULL, 0); +static SENSOR_DEVICE_ATTR(code_ver, S_IRUGO, show_cpld_version, NULL, 0); static SENSOR_DEVICE_ATTR(scratch, S_IRUGO | S_IWUSR, show_scratch, set_scratch, 0); static SENSOR_DEVICE_ATTR(psu2_alert, S_IRUGO, show_psu1_reg, NULL, SWPLD1_PSU1_REG_PSU2_INT); @@ -690,7 +690,7 @@ static struct attribute *nokia_7220_h3_swpld1_attributes[] = { &sensor_dev_attr_swbd_id.dev_attr.attr, &sensor_dev_attr_swbd_version.dev_attr.attr, &sensor_dev_attr_cpld_type.dev_attr.attr, - &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_code_ver.dev_attr.attr, &sensor_dev_attr_scratch.dev_attr.attr, &sensor_dev_attr_psu2_alert.dev_attr.attr, @@ -811,7 +811,7 @@ static int nokia_7220_h3_swpld1_probe(struct i2c_client *client) data->swbd_id = nokia_7220_h3_swpld_read(data, SWPLD1_SWBD_ID_REG); data->swbd_version = nokia_7220_h3_swpld_read(data, SWPLD1_SWBD_VER_REG); data->cpld_type = nokia_7220_h3_swpld_read(data, SWPLD1_CPLD_REV_REG) >> SWPLD1_CPLD_REV_REG_TYPE; - data->cpld_version = nokia_7220_h3_swpld_read(data, SWPLD1_CPLD_REV_REG) & SWPLD1_CPLD_REV_REG_MSK; + data->code_ver = nokia_7220_h3_swpld_read(data, SWPLD1_CPLD_REV_REG) & SWPLD1_CPLD_REV_REG_MSK; return 0; diff --git a/ixr7220h3/modules/nokia_7220_h3_swpld2.c b/ixr7220h3/modules/nokia_7220_h3_swpld2.c index 2ce23e3..8891524 100644 --- a/ixr7220h3/modules/nokia_7220_h3_swpld2.c +++ b/ixr7220h3/modules/nokia_7220_h3_swpld2.c @@ -1,6 +1,6 @@ // * CPLD driver for Nokia-7220-IXR-H3 Router // * -// * Copyright (C) 2024 Nokia Corporation. +// * Copyright (C) 2023 Nokia Corporation. // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ #include #include #include +#include #define DRIVER_NAME "nokia_7220h3_swpld2" @@ -70,8 +71,9 @@ static const unsigned short cpld_address_list[] = {0x34, I2C_CLIENT_END}; struct cpld_data { struct i2c_client *client; struct mutex update_lock; - int cpld_version; + int code_ver; int cpld_type; + int reset_list[16]; }; static int nokia_7220_h3_swpld_read(struct cpld_data *data, u8 reg) @@ -102,10 +104,34 @@ static void nokia_7220_h3_swpld_write(struct cpld_data *data, u8 reg, u8 value) mutex_unlock(&data->update_lock); } -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *devattr, char *buf) +static void dump_reg(struct cpld_data *data) +{ + struct i2c_client *client = data->client; + u8 val0 = 0; + u8 val1 = 0; + + val0 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP01_08_RSTN_REG); + val1 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP09_16_RSTN_REG); + dev_info(&client->dev, "[SWPLD2]QSFP_RESET_REG: 0x%02x, 0x%02x\n", val0, val1); + + val0 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP01_08_INITMOD_REG); + val1 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP09_16_INITMOD_REG); + dev_info(&client->dev, "[SWPLD2]QSFP_LPMODE_REG: 0x%02x, 0x%02x\n", val0, val1); + + val0 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP01_08_MODSEL_REG); + val1 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP09_16_MODSEL_REG); + dev_info(&client->dev, "[SWPLD2]QSFP_MODSEL_REG: 0x%02x, 0x%02x\n", val0, val1); + + val0 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP01_08_MODPRS_REG); + val1 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP09_16_MODPRS_REG); + dev_info(&client->dev, "[SWPLD2]QSFP_MODPRES_REG: 0x%02x, 0x%02x\n", val0, val1); + +} + +static ssize_t show_code_ver(struct device *dev, struct device_attribute *devattr, char *buf) { struct cpld_data *data = dev_get_drvdata(dev); - return sprintf(buf, "0x%02x\n", data->cpld_version); + return sprintf(buf, "0x%02x\n", data->code_ver); } static ssize_t show_cpld_type(struct device *dev, struct device_attribute *devattr, char *buf) @@ -394,6 +420,20 @@ static ssize_t show_qsfp_g2_prs(struct device *dev, struct device_attribute *dev return sprintf(buf, "%d\n", (val>>sda->index) & 0x1 ? 1:0); } +static ssize_t show_modprs_reg(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); + u8 val = 0; + + if (sda->index == 1) + val = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP01_08_MODPRS_REG); + if (sda->index == 2) + val = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP09_16_MODPRS_REG); + + return sprintf(buf, "0x%02x\n", val); +} + static ssize_t show_qsfp_g1_intn(struct device *dev, struct device_attribute *devattr, char *buf) { struct cpld_data *data = dev_get_drvdata(dev); @@ -416,8 +456,34 @@ static ssize_t show_qsfp_g2_intn(struct device *dev, struct device_attribute *de return sprintf(buf, "%d\n", (val>>sda->index) & 0x1 ? 1:0); } +static ssize_t show_qsfp_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); + + return sprintf(buf, "%d\n", data->reset_list[sda->index]); +} + +static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); + u8 usr_val = 0; + + int ret = kstrtou8(buf, 10, &usr_val); + if (ret != 0) { + return ret; + } + if (usr_val > 0xFF) { + return -EINVAL; + } + + data->reset_list[sda->index] = usr_val; + return count; +} + // sysfs attributes -static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, show_cpld_version, NULL, 0); +static SENSOR_DEVICE_ATTR(code_ver, S_IRUGO, show_code_ver, NULL, 0); static SENSOR_DEVICE_ATTR(cpld_type, S_IRUGO, show_cpld_type, NULL, SWPLD23_REV_REG_TYPE); static SENSOR_DEVICE_ATTR(scratch, S_IRUGO | S_IWUSR, show_scratch, set_scratch, 0); @@ -488,6 +554,8 @@ static SENSOR_DEVICE_ATTR(qsfp13_prs, S_IRUGO, show_qsfp_g2_prs, NULL, QSFP13_IN static SENSOR_DEVICE_ATTR(qsfp14_prs, S_IRUGO, show_qsfp_g2_prs, NULL, QSFP14_INDEX); static SENSOR_DEVICE_ATTR(qsfp15_prs, S_IRUGO, show_qsfp_g2_prs, NULL, QSFP15_INDEX); static SENSOR_DEVICE_ATTR(qsfp16_prs, S_IRUGO, show_qsfp_g2_prs, NULL, QSFP16_INDEX); +static SENSOR_DEVICE_ATTR(modprs_reg1, S_IRUGO, show_modprs_reg, NULL, 1); +static SENSOR_DEVICE_ATTR(modprs_reg2, S_IRUGO, show_modprs_reg, NULL, 2); static SENSOR_DEVICE_ATTR(qsfp1_intn, S_IRUGO, show_qsfp_g1_intn, NULL, QSFP01_INDEX); static SENSOR_DEVICE_ATTR(qsfp2_intn, S_IRUGO, show_qsfp_g1_intn, NULL, QSFP02_INDEX); @@ -506,8 +574,26 @@ static SENSOR_DEVICE_ATTR(qsfp14_intn, S_IRUGO, show_qsfp_g2_intn, NULL, QSFP14_ static SENSOR_DEVICE_ATTR(qsfp15_intn, S_IRUGO, show_qsfp_g2_intn, NULL, QSFP15_INDEX); static SENSOR_DEVICE_ATTR(qsfp16_intn, S_IRUGO, show_qsfp_g2_intn, NULL, QSFP16_INDEX); +static SENSOR_DEVICE_ATTR(qsfp1_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 0); +static SENSOR_DEVICE_ATTR(qsfp2_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 1); +static SENSOR_DEVICE_ATTR(qsfp3_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 2); +static SENSOR_DEVICE_ATTR(qsfp4_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 3); +static SENSOR_DEVICE_ATTR(qsfp5_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 4); +static SENSOR_DEVICE_ATTR(qsfp6_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 5); +static SENSOR_DEVICE_ATTR(qsfp7_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 6); +static SENSOR_DEVICE_ATTR(qsfp8_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 7); +static SENSOR_DEVICE_ATTR(qsfp9_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 8); +static SENSOR_DEVICE_ATTR(qsfp10_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 9); +static SENSOR_DEVICE_ATTR(qsfp11_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 10); +static SENSOR_DEVICE_ATTR(qsfp12_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 11); +static SENSOR_DEVICE_ATTR(qsfp13_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 12); +static SENSOR_DEVICE_ATTR(qsfp14_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 13); +static SENSOR_DEVICE_ATTR(qsfp15_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 14); +static SENSOR_DEVICE_ATTR(qsfp16_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 15); + + static struct attribute *nokia_7220_h3_swpld2_attributes[] = { - &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_code_ver.dev_attr.attr, &sensor_dev_attr_cpld_type.dev_attr.attr, &sensor_dev_attr_scratch.dev_attr.attr, @@ -578,6 +664,8 @@ static struct attribute *nokia_7220_h3_swpld2_attributes[] = { &sensor_dev_attr_qsfp14_prs.dev_attr.attr, &sensor_dev_attr_qsfp15_prs.dev_attr.attr, &sensor_dev_attr_qsfp16_prs.dev_attr.attr, + &sensor_dev_attr_modprs_reg1.dev_attr.attr, + &sensor_dev_attr_modprs_reg2.dev_attr.attr, &sensor_dev_attr_qsfp1_intn.dev_attr.attr, &sensor_dev_attr_qsfp2_intn.dev_attr.attr, @@ -594,7 +682,24 @@ static struct attribute *nokia_7220_h3_swpld2_attributes[] = { &sensor_dev_attr_qsfp13_intn.dev_attr.attr, &sensor_dev_attr_qsfp14_intn.dev_attr.attr, &sensor_dev_attr_qsfp15_intn.dev_attr.attr, - &sensor_dev_attr_qsfp16_intn.dev_attr.attr, + &sensor_dev_attr_qsfp16_intn.dev_attr.attr, + + &sensor_dev_attr_qsfp1_reset.dev_attr.attr, + &sensor_dev_attr_qsfp2_reset.dev_attr.attr, + &sensor_dev_attr_qsfp3_reset.dev_attr.attr, + &sensor_dev_attr_qsfp4_reset.dev_attr.attr, + &sensor_dev_attr_qsfp5_reset.dev_attr.attr, + &sensor_dev_attr_qsfp6_reset.dev_attr.attr, + &sensor_dev_attr_qsfp7_reset.dev_attr.attr, + &sensor_dev_attr_qsfp8_reset.dev_attr.attr, + &sensor_dev_attr_qsfp9_reset.dev_attr.attr, + &sensor_dev_attr_qsfp10_reset.dev_attr.attr, + &sensor_dev_attr_qsfp11_reset.dev_attr.attr, + &sensor_dev_attr_qsfp12_reset.dev_attr.attr, + &sensor_dev_attr_qsfp13_reset.dev_attr.attr, + &sensor_dev_attr_qsfp14_reset.dev_attr.attr, + &sensor_dev_attr_qsfp15_reset.dev_attr.attr, + &sensor_dev_attr_qsfp16_reset.dev_attr.attr, NULL }; @@ -605,7 +710,8 @@ static const struct attribute_group nokia_7220_h3_swpld2_group = { static int nokia_7220_h3_swpld2_probe(struct i2c_client *client) { int status; - struct cpld_data *data = NULL; + struct cpld_data *data = NULL; + int i; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&client->dev, "CPLD PROBE ERROR: i2c_check_functionality failed (0x%x)\n", client->addr); @@ -632,8 +738,22 @@ static int nokia_7220_h3_swpld2_probe(struct i2c_client *client) goto exit; } - data->cpld_version = nokia_7220_h3_swpld_read(data, SWPLD23_REV_REG) & SWPLD23_REV_REG_MSK; - data->cpld_type = nokia_7220_h3_swpld_read(data, SWPLD23_REV_REG) >> SWPLD23_REV_REG_TYPE; + data->code_ver = nokia_7220_h3_swpld_read(data, SWPLD23_REV_REG) & SWPLD23_REV_REG_MSK; + data->cpld_type = nokia_7220_h3_swpld_read(data, SWPLD23_REV_REG) >> SWPLD23_REV_REG_TYPE; + dump_reg(data); + dev_info(&client->dev, "[SWPLD2]Reseting QSFPs and SWPLD Registers...\n"); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP01_08_MODSEL_REG, 0x0); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP09_16_MODSEL_REG, 0x0); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP01_08_INITMOD_REG, 0xFF); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP09_16_INITMOD_REG, 0xFF); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP01_08_RSTN_REG, 0x0); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP09_16_RSTN_REG, 0x0); + msleep(500); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP01_08_RSTN_REG, 0xFF); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP09_16_RSTN_REG, 0xFF); + dev_info(&client->dev, "[SWPLD2]QSFPs and SWPLD Registers reset done.\n"); + dump_reg(data); + for (i=0;i<16;i++) data->reset_list[i] = 0; return 0; diff --git a/ixr7220h3/modules/nokia_7220_h3_swpld3.c b/ixr7220h3/modules/nokia_7220_h3_swpld3.c index ddbfc75..83ab4a5 100644 --- a/ixr7220h3/modules/nokia_7220_h3_swpld3.c +++ b/ixr7220h3/modules/nokia_7220_h3_swpld3.c @@ -1,6 +1,6 @@ // * CPLD driver for Nokia-7220-IXR-H3 Router // * -// * Copyright (C) 2024 Nokia Corporation. +// * Copyright (C) 2023 Nokia Corporation. // * // * This program is free software: you can redistribute it and/or modify // * it under the terms of the GNU General Public License as published by @@ -24,6 +24,7 @@ #include #include #include +#include #define DRIVER_NAME "nokia_7220h3_swpld3" @@ -81,8 +82,9 @@ static const unsigned short cpld_address_list[] = {0x35, I2C_CLIENT_END}; struct cpld_data { struct i2c_client *client; struct mutex update_lock; - int cpld_version; + int code_ver; int cpld_type; + int reset_list[16]; }; static int nokia_7220_h3_swpld_read(struct cpld_data *data, u8 reg) @@ -113,10 +115,34 @@ static void nokia_7220_h3_swpld_write(struct cpld_data *data, u8 reg, u8 value) mutex_unlock(&data->update_lock); } -static ssize_t show_cpld_version(struct device *dev, struct device_attribute *devattr, char *buf) +static void dump_reg(struct cpld_data *data) +{ + struct i2c_client *client = data->client; + u8 val0 = 0; + u8 val1 = 0; + + val0 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP17_24_RSTN_REG); + val1 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP25_32_RSTN_REG); + dev_info(&client->dev, "[SWPLD3]QSFP_RESET_REG: 0x%02x, 0x%02x\n", val0, val1); + + val0 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP17_24_INITMOD_REG); + val1 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP25_32_INITMOD_REG); + dev_info(&client->dev, "[SWPLD3]QSFP_LPMODE_REG: 0x%02x, 0x%02x\n", val0, val1); + + val0 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP17_24_MODSEL_REG); + val1 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP25_32_MODSEL_REG); + dev_info(&client->dev, "[SWPLD3]QSFP_MODSEL_REG: 0x%02x, 0x%02x\n", val0, val1); + + val0 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP17_24_MODPRS_REG); + val1 = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP25_32_MODPRS_REG); + dev_info(&client->dev, "[SWPLD3]QSFP_MODPRES_REG: 0x%02x, 0x%02x\n", val0, val1); + +} + +static ssize_t show_code_ver(struct device *dev, struct device_attribute *devattr, char *buf) { struct cpld_data *data = dev_get_drvdata(dev); - return sprintf(buf, "0x%02x\n", data->cpld_version); + return sprintf(buf, "0x%02x\n", data->code_ver); } static ssize_t show_cpld_type(struct device *dev, struct device_attribute *devattr, char *buf) @@ -405,6 +431,20 @@ static ssize_t show_qsfp_g4_prs(struct device *dev, struct device_attribute *dev return sprintf(buf, "%d\n", (val>>sda->index) & 0x1 ? 1:0); } +static ssize_t show_modprs_reg(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); + u8 val = 0; + + if (sda->index == 1) + val = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP17_24_MODPRS_REG); + if (sda->index == 2) + val = nokia_7220_h3_swpld_read(data, SWPLD23_QSFP25_32_MODPRS_REG); + + return sprintf(buf, "0x%02x\n", val); +} + static ssize_t show_qsfp_g3_intn(struct device *dev, struct device_attribute *devattr, char *buf) { struct cpld_data *data = dev_get_drvdata(dev); @@ -474,8 +514,34 @@ static ssize_t set_sfp_reg2(struct device *dev, struct device_attribute *devattr return count; } +static ssize_t show_qsfp_reset(struct device *dev, struct device_attribute *devattr, char *buf) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); + + return sprintf(buf, "%d\n", data->reset_list[sda->index]); +} + +static ssize_t set_qsfp_reset(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) +{ + struct cpld_data *data = dev_get_drvdata(dev); + struct sensor_device_attribute *sda = to_sensor_dev_attr(devattr); + u8 usr_val = 0; + + int ret = kstrtou8(buf, 10, &usr_val); + if (ret != 0) { + return ret; + } + if (usr_val > 0xFF) { + return -EINVAL; + } + + data->reset_list[sda->index] = usr_val; + return count; +} + // sysfs attributes -static SENSOR_DEVICE_ATTR(cpld_version, S_IRUGO, show_cpld_version, NULL, 0); +static SENSOR_DEVICE_ATTR(code_ver, S_IRUGO, show_code_ver, NULL, 0); static SENSOR_DEVICE_ATTR(cpld_type, S_IRUGO, show_cpld_type, NULL, SWPLD23_REV_REG_TYPE); static SENSOR_DEVICE_ATTR(scratch, S_IRUGO | S_IWUSR, show_scratch, set_scratch, 0); @@ -546,6 +612,8 @@ static SENSOR_DEVICE_ATTR(qsfp29_prs, S_IRUGO, show_qsfp_g4_prs, NULL, QSFP29_IN static SENSOR_DEVICE_ATTR(qsfp30_prs, S_IRUGO, show_qsfp_g4_prs, NULL, QSFP30_INDEX); static SENSOR_DEVICE_ATTR(qsfp31_prs, S_IRUGO, show_qsfp_g4_prs, NULL, QSFP31_INDEX); static SENSOR_DEVICE_ATTR(qsfp32_prs, S_IRUGO, show_qsfp_g4_prs, NULL, QSFP32_INDEX); +static SENSOR_DEVICE_ATTR(modprs_reg1, S_IRUGO, show_modprs_reg, NULL, 1); +static SENSOR_DEVICE_ATTR(modprs_reg2, S_IRUGO, show_modprs_reg, NULL, 2); static SENSOR_DEVICE_ATTR(qsfp17_intn, S_IRUGO, show_qsfp_g3_intn, NULL, QSFP17_INDEX); static SENSOR_DEVICE_ATTR(qsfp18_intn, S_IRUGO, show_qsfp_g3_intn, NULL, QSFP18_INDEX); @@ -574,8 +642,25 @@ static SENSOR_DEVICE_ATTR(sfp1_txfault, S_IRUGO, show_sfp_reg1, NULL, SWPLD23_SF static SENSOR_DEVICE_ATTR(sfp0_txdis, S_IRUGO | S_IWUSR, show_sfp_reg2, set_sfp_reg2, SWPLD23_SFP_REG2_P0_TXDIS); static SENSOR_DEVICE_ATTR(sfp1_txdis, S_IRUGO | S_IWUSR, show_sfp_reg2, set_sfp_reg2, SWPLD23_SFP_REG2_P1_TXDIS); +static SENSOR_DEVICE_ATTR(qsfp17_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 0); +static SENSOR_DEVICE_ATTR(qsfp18_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 1); +static SENSOR_DEVICE_ATTR(qsfp19_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 2); +static SENSOR_DEVICE_ATTR(qsfp20_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 3); +static SENSOR_DEVICE_ATTR(qsfp21_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 4); +static SENSOR_DEVICE_ATTR(qsfp22_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 5); +static SENSOR_DEVICE_ATTR(qsfp23_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 6); +static SENSOR_DEVICE_ATTR(qsfp24_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 7); +static SENSOR_DEVICE_ATTR(qsfp25_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 8); +static SENSOR_DEVICE_ATTR(qsfp26_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 9); +static SENSOR_DEVICE_ATTR(qsfp27_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 10); +static SENSOR_DEVICE_ATTR(qsfp28_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 11); +static SENSOR_DEVICE_ATTR(qsfp29_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 12); +static SENSOR_DEVICE_ATTR(qsfp30_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 13); +static SENSOR_DEVICE_ATTR(qsfp31_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 14); +static SENSOR_DEVICE_ATTR(qsfp32_reset, S_IRUGO | S_IWUSR, show_qsfp_reset, set_qsfp_reset, 15); + static struct attribute *nokia_7220_h3_swpld3_attributes[] = { - &sensor_dev_attr_cpld_version.dev_attr.attr, + &sensor_dev_attr_code_ver.dev_attr.attr, &sensor_dev_attr_cpld_type.dev_attr.attr, &sensor_dev_attr_scratch.dev_attr.attr, @@ -646,6 +731,8 @@ static struct attribute *nokia_7220_h3_swpld3_attributes[] = { &sensor_dev_attr_qsfp30_prs.dev_attr.attr, &sensor_dev_attr_qsfp31_prs.dev_attr.attr, &sensor_dev_attr_qsfp32_prs.dev_attr.attr, + &sensor_dev_attr_modprs_reg1.dev_attr.attr, + &sensor_dev_attr_modprs_reg2.dev_attr.attr, &sensor_dev_attr_qsfp17_intn.dev_attr.attr, &sensor_dev_attr_qsfp18_intn.dev_attr.attr, @@ -673,6 +760,23 @@ static struct attribute *nokia_7220_h3_swpld3_attributes[] = { &sensor_dev_attr_sfp0_txdis.dev_attr.attr, &sensor_dev_attr_sfp1_txdis.dev_attr.attr, + + &sensor_dev_attr_qsfp17_reset.dev_attr.attr, + &sensor_dev_attr_qsfp18_reset.dev_attr.attr, + &sensor_dev_attr_qsfp19_reset.dev_attr.attr, + &sensor_dev_attr_qsfp20_reset.dev_attr.attr, + &sensor_dev_attr_qsfp21_reset.dev_attr.attr, + &sensor_dev_attr_qsfp22_reset.dev_attr.attr, + &sensor_dev_attr_qsfp23_reset.dev_attr.attr, + &sensor_dev_attr_qsfp24_reset.dev_attr.attr, + &sensor_dev_attr_qsfp25_reset.dev_attr.attr, + &sensor_dev_attr_qsfp26_reset.dev_attr.attr, + &sensor_dev_attr_qsfp27_reset.dev_attr.attr, + &sensor_dev_attr_qsfp28_reset.dev_attr.attr, + &sensor_dev_attr_qsfp29_reset.dev_attr.attr, + &sensor_dev_attr_qsfp30_reset.dev_attr.attr, + &sensor_dev_attr_qsfp31_reset.dev_attr.attr, + &sensor_dev_attr_qsfp32_reset.dev_attr.attr, NULL }; @@ -683,7 +787,8 @@ static const struct attribute_group nokia_7220_h3_swpld3_group = { static int nokia_7220_h3_swpld3_probe(struct i2c_client *client) { int status; - struct cpld_data *data = NULL; + struct cpld_data *data = NULL; + int i; if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) { dev_err(&client->dev, "CPLD PROBE ERROR: i2c_check_functionality failed (0x%x)\n", client->addr); @@ -710,8 +815,23 @@ static int nokia_7220_h3_swpld3_probe(struct i2c_client *client) goto exit; } - data->cpld_version = nokia_7220_h3_swpld_read(data, SWPLD23_REV_REG) & SWPLD23_REV_REG_MSK; - data->cpld_type = nokia_7220_h3_swpld_read(data, SWPLD23_REV_REG) >> SWPLD23_REV_REG_TYPE; + data->code_ver = nokia_7220_h3_swpld_read(data, SWPLD23_REV_REG) & SWPLD23_REV_REG_MSK; + data->cpld_type = nokia_7220_h3_swpld_read(data, SWPLD23_REV_REG) >> SWPLD23_REV_REG_TYPE; + dump_reg(data); + dev_info(&client->dev, "[SWPLD3]Reseting QSFPs and SWPLD Registers...\n"); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP17_24_MODSEL_REG, 0x0); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP25_32_MODSEL_REG, 0x0); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP17_24_INITMOD_REG, 0xFF); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP25_32_INITMOD_REG, 0xFF); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP17_24_RSTN_REG, 0x0); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP25_32_RSTN_REG, 0x0); + msleep(500); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP17_24_RSTN_REG, 0xFF); + nokia_7220_h3_swpld_write(data, SWPLD23_QSFP25_32_RSTN_REG, 0xFF); + nokia_7220_h3_swpld_write(data, SWPLD23_SFP_REG2, 0x0); + dev_info(&client->dev, "[SWPLD3]QSFPs and SWPLD Registers reset done.\n"); + dump_reg(data); + for (i=0;i<16;i++) data->reset_list[i] = 0; return 0; diff --git a/ixr7220h3/scripts/ixr7220h3_platform_init.sh b/ixr7220h3/scripts/ixr7220h3_platform_init.sh index 70600d9..a54a5ba 100755 --- a/ixr7220h3/scripts/ixr7220h3_platform_init.sh +++ b/ixr7220h3/scripts/ixr7220h3_platform_init.sh @@ -121,6 +121,13 @@ echo ir35221 0x10 > /sys/bus/i2c/devices/i2c-15/new_device # Enumerate Voltage Ragulator (3V3) echo tps53667 0x64 > /sys/bus/i2c/devices/i2c-15/new_device +# Set the PCA9548 mux behavior +echo -2 > /sys/bus/i2c/devices/3-0070/idle_state +echo -2 > /sys/bus/i2c/devices/3-0071/idle_state +echo -2 > /sys/bus/i2c/devices/3-0072/idle_state +echo -2 > /sys/bus/i2c/devices/3-0073/idle_state +echo -2 > /sys/bus/i2c/devices/3-0074/idle_state + #Enumerate CPLDs echo nokia_7220h3_cpupld 0x31 > /sys/bus/i2c/devices/i2c-0/new_device echo nokia_7220h3_swpld1 0x32 > /sys/bus/i2c/devices/i2c-17/new_device @@ -158,6 +165,8 @@ nokia_7220H3_profile for port in {4..9} do echo 1022${port} > /sys/class/gpio/export + echo in > /sys/class/gpio/gpio1022${port}/direction + sleep 0.1 done for fan in {58..63} @@ -165,11 +174,4 @@ do chmod 644 /sys/bus/i2c/devices/${fan}-0050/eeprom done -# Set the PCA9548 mux behavior -echo -2 > /sys/bus/i2c/devices/3-0070/idle_state -echo -2 > /sys/bus/i2c/devices/3-0071/idle_state -echo -2 > /sys/bus/i2c/devices/3-0072/idle_state -echo -2 > /sys/bus/i2c/devices/3-0073/idle_state -echo -2 > /sys/bus/i2c/devices/3-0074/idle_state - exit 0 diff --git a/ixr7220h3/sonic_platform/chassis.py b/ixr7220h3/sonic_platform/chassis.py index 4da7031..fd3e761 100644 --- a/ixr7220h3/sonic_platform/chassis.py +++ b/ixr7220h3/sonic_platform/chassis.py @@ -37,19 +37,21 @@ MAX_7220H3_FANS_PER_DRAWER = 2 MAX_7220H3_PSU = 2 MAX_7220H3_THERMAL = 7 -MAX_7220H3_COMPONENT = 4 +MAX_7220H3_COMPONENT = 5 SYSLOG_IDENTIFIER = "chassis" sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) +#sonic_logger.set_min_log_priority_info() class Chassis(ChassisBase): """ Nokia platform-specific Chassis class customized for the 7220 H3 platform. - """ - + """ + def __init__(self): ChassisBase.__init__(self) + self.system_led_supported_color = ['off', 'amber', 'green', 'amber_blink', 'green_blink'] # Port numbers for SFP List Initialization self.PORT_START = PORT_START @@ -58,7 +60,7 @@ def __init__(self): # Verify optoe driver QSFP-DD eeprom devices were enumerated and exist # then create the sfp nodes eeprom_path = "/sys/bus/i2c/devices/{0}-0050/eeprom" - mux_dev = sorted(glob.glob("/sys/bus/i2c/devices/i2c-0/0-0077/channel-1/i2c-[1-4][0-9]")) + mux_dev = sorted(glob.glob("/sys/bus/i2c/devices/i2c-0/0-0077/channel-1/i2c-[1-4][0-9]")) y = 0 for index in range(PORT_START, PORT_START + QSFP_PORT_NUM): @@ -69,23 +71,22 @@ def __init__(self): if not os.path.exists(port_eeprom_path): sonic_logger.log_info("path %s didnt exist" % port_eeprom_path) sfp_node = Sfp(index, 'QSFPDD', port_eeprom_path, port_i2c_map) - self._sfp_list.append(sfp_node) - + self._sfp_list.append(sfp_node) port_eeprom_path = "/sys/bus/i2c/devices/50-0050/eeprom" if not os.path.exists(port_eeprom_path): - sonic_logger.log_info("path %s didnt exist" % port_eeprom_path) + sonic_logger.log_info("path %s didnt exist" % port_eeprom_path) sfp_node = Sfp(QSFP_PORT_NUM + 1, 'SFP+', port_eeprom_path, 50) self._sfp_list.append(sfp_node) - self.sfp_event_initialized = False - - port_eeprom_path = "/sys/bus/i2c/devices/50-0051/eeprom" + port_eeprom_path = "/sys/bus/i2c/devices/51-0050/eeprom" if not os.path.exists(port_eeprom_path): - sonic_logger.log_info("path %s didnt exist" % port_eeprom_path) + sonic_logger.log_info("path %s didnt exist" % port_eeprom_path) sfp_node = Sfp(QSFP_PORT_NUM + 2, 'SFP+', port_eeprom_path, 51) self._sfp_list.append(sfp_node) + self.sfp_event_initialized = False + # Instantiate system eeprom object self._eeprom = Eeprom(False, 0, False, 0) @@ -124,6 +125,7 @@ def _read_sysfs_file(self, sysfs_file): try: with open(sysfs_file, 'r') as fd: rv = fd.read() + fd.close() except Exception as e: rv = 'ERR' @@ -141,6 +143,7 @@ def _write_sysfs_file(self, sysfs_file, value): try: with open(sysfs_file, 'w') as fd: rv = fd.write(value) + fd.close() except Exception as e: rv = 'ERR' @@ -195,7 +198,7 @@ def get_change_event(self, timeout=0): Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0'}} indicates that fan 0 has been removed, fan 2 has been inserted and sfp 11 has been removed. - """ + """ # Initialize SFP event first if not self.sfp_event_initialized: from sonic_platform.sfp_event import sfp_event @@ -327,21 +330,19 @@ def get_reboot_cause(self): is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used to pass a description of the reboot cause. """ - result = self._read_sysfs_file(CPUPLD_DIR+"cold_reset") - if result == '1': - return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Cold Reset") + result = self._read_sysfs_file(CPUPLD_DIR + "cpu_sys_rst") - result = self._read_sysfs_file(CPUPLD_DIR+"warm_reset") - if result == '1': - return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Warm Reset") + if (int(result, 16) & 0x10) >> 4 == 1: + return (self.REBOOT_CAUSE_WATCHDOG, None) + + if (int(result, 16) & 0x01) == 1: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Power Error") - result = self._read_sysfs_file(CPUPLD_DIR+"wd_reset") - if result == '1': - return (self.REBOOT_CAUSE_WATCHDOG, None) + if (int(result, 16) & 0x80) >> 7 == 1: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Cold Reset") - result = self._read_sysfs_file(CPUPLD_DIR+"cpu_pwr_err") - if result == '1': - return (self.REBOOT_CAUSE_POWER_LOSS, None) + if (int(result, 16) & 0x40) >> 6 == 1: + return (self.REBOOT_CAUSE_HARDWARE_OTHER, "Warm Reset") return (self.REBOOT_CAUSE_NON_HARDWARE, None) @@ -363,8 +364,7 @@ def get_watchdog(self): try: if self._watchdog is None: from sonic_platform.watchdog import WatchdogImplBase - watchdog_device_path = "/dev/watchdog0" - self._watchdog = WatchdogImplBase(watchdog_device_path) + self._watchdog = WatchdogImplBase() except Exception as e: sonic_logger.log_warning(" Fail to load watchdog {}".format(repr(e))) @@ -404,16 +404,16 @@ def set_status_led(self, color): if color not in self.system_led_supported_color: return False - if (color == 'off'): - value = '5' + if (color == 'green'): + value = '1' + elif (color == 'green_blink'): + value = '2' elif (color == 'amber'): value = '3' - elif (color == 'green'): - value = '1' elif (color == 'amber_blink'): value = '4' - elif (color == 'green_blink'): - value = '2' + elif (color == 'off'): + value = '0' else: return False # Write sys led diff --git a/ixr7220h3/sonic_platform/component.py b/ixr7220h3/sonic_platform/component.py index eca2b60..b0c123d 100644 --- a/ixr7220h3/sonic_platform/component.py +++ b/ixr7220h3/sonic_platform/component.py @@ -24,8 +24,11 @@ else: import subprocess as cmd +MAX_7220H3_COMPONENT = 5 +BIOS_VERSION_PATH = "/sys/class/dmi/id/bios_version" -CPLD_DIR = ["/sys/bus/i2c/devices/0-0031/", +CPLD_DIR = [" ", + "/sys/bus/i2c/devices/0-0031/", "/sys/bus/i2c/devices/17-0032/", "/sys/bus/i2c/devices/17-0034/", "/sys/bus/i2c/devices/17-0035/"] @@ -34,12 +37,13 @@ class Component(ComponentBase): """Nokia platform-specific Component class""" CHASSIS_COMPONENTS = [ - ["CPU-PLD", "Used for managing CPU board "], - ["SW1-PLD", "Used for managing BCM chip, SFPs, PSUs and LEDs "], - ["SW2-PLD", "Used for managing QSFP-DD 1-16 "], - ["SW3-PLD", "Used for managing QSFP-DD 17-32, SFP+ "] ] + ["BIOS", "Basic Input/Output System"], + ["CPUPLD", "Used for managing CPU board "], + ["SWPLD1", "Used for managing BCM chip, SFPs, PSUs and LEDs "], + ["SWPLD2", "Used for managing QSFP-DD 1-16 "], + ["SWPLD3", "Used for managing QSFP-DD 17-32, SFP+ "] ] - CPLD_UPDATE_COMMAND = ['./cpldupd_h3', ''] + CPLD_UPDATE_COMMAND = ['./h3_cpld', ''] def __init__(self, component_index): self.index = component_index @@ -69,6 +73,7 @@ def _read_sysfs_file(self, sysfs_file): try: with open(sysfs_file, 'r') as fd: rv = fd.read() + fd.close() except Exception as e: rv = 'ERR' @@ -86,6 +91,7 @@ def _write_sysfs_file(self, sysfs_file, value): try: with open(sysfs_file, 'w') as fd: rv = fd.write(value) + fd.close() except Exception as e: rv = 'ERR' @@ -98,13 +104,13 @@ def _write_sysfs_file(self, sysfs_file, value): return rv def _get_cpld_version(self, cpld_number): - - if self.index == 0: - return self._read_sysfs_file(self.cpld_dir + "cpld_major_version") - elif self.index <= 3: - return self._read_sysfs_file(self.cpld_dir + "cpld_version") + + if self.name == "BIOS": + return self._read_sysfs_file(BIOS_VERSION_PATH) + elif self.index < MAX_7220H3_COMPONENT: + return self._read_sysfs_file(self.cpld_dir + "code_ver") else: - return 'NA' + return 'NA' def get_name(self): """ @@ -180,11 +186,8 @@ def get_firmware_version(self): Returns: A string containing the firmware version of the component """ - if self.index == 0: - return self._read_sysfs_file(self.cpld_dir + "cpld_minor_version") - if self.index <= 3: - return self._get_cpld_version(self.index) - + return self._get_cpld_version(self.index) + def install_firmware(self, image_path): """ Installs firmware to the component @@ -204,8 +207,8 @@ def install_firmware(self, image_path): return False # check whether the cpld exe exists - if not os.path.isfile('/tmp/cpldupd_h3'): - print("ERROR: the cpld exe {} doesn't exist ".format('/tmp/cpldupd_h3')) + if not os.path.isfile('/tmp/h3_cpld'): + print("ERROR: the cpld exe {} doesn't exist ".format('/tmp/h3_cpld')) return False self.CPLD_UPDATE_COMMAND[1] = image_name diff --git a/ixr7220h3/sonic_platform/fan.py b/ixr7220h3/sonic_platform/fan.py index 5cd8b57..240d59f 100644 --- a/ixr7220h3/sonic_platform/fan.py +++ b/ixr7220h3/sonic_platform/fan.py @@ -17,8 +17,9 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -MAX_7220H3_FANS_PER_DRAWER = 2 - +H3_FANS_PER_DRAWER = 2 +FAN_PN_F2B = "3HE16436AA" +FAN_PN_B2F = "3HE16437AA" FORWARD_FAN_F_SPEED = 23000 FORWARD_FAN_R_SPEED = 20500 FORWARD_FAN_TOLERANCE = 50 #8 @@ -56,12 +57,13 @@ def __init__(self, fan_index, drawer_index, psu_fan=False, dependency=None): if not self.is_psu_fan: # Fan is 1-based in Nokia platforms - self.index = drawer_index * MAX_7220H3_FANS_PER_DRAWER + fan_index + 1 - self.fan_drawer = drawer_index + self.index = drawer_index * H3_FANS_PER_DRAWER + fan_index + 1 + self.drawer_index = drawer_index fan_index_emc230x = FAN_INDEX_IN_DRAWER[drawer_index][fan_index] self.set_fan_speed_reg = hwmon_path[0] + "pwm{}".format(fan_index_emc230x) self.get_fan_speed_reg = hwmon_path[0] + "fan{}_input".format(fan_index_emc230x) self.gpio_dir = GPIO_DIR.format(GPIO_PORT[drawer_index]) + self.system_led_supported_color = ['off', 'amber', 'green'] # Fan eeprom self.eeprom = Eeprom(False, 0, True, drawer_index) @@ -69,22 +71,13 @@ def __init__(self, fan_index, drawer_index, psu_fan=False, dependency=None): if self.get_direction() == self.FAN_DIRECTION_EXHAUST: if fan_index == 0: self.std_fan_speed = REVERSE_FAN_F_SPEED - #self.max_fan_speed = REVERSE_FAN_F_SPEED * (1 + REVERSE_FAN_TOLERANCE / 100) - #self.min_fan_speed = REVERSE_FAN_F_SPEED * (1 - REVERSE_FAN_TOLERANCE / 100) else: - self.std_fan_speed = REVERSE_FAN_R_SPEED - #self.max_fan_speed = REVERSE_FAN_R_SPEED * (1 + REVERSE_FAN_TOLERANCE / 100) - #self.min_fan_speed = REVERSE_FAN_R_SPEED * (1 - REVERSE_FAN_TOLERANCE / 100) + self.std_fan_speed = REVERSE_FAN_R_SPEED else: if fan_index == 0: self.std_fan_speed = FORWARD_FAN_F_SPEED - #self.max_fan_speed = FORWARD_FAN_F_SPEED * (1 + FORWARD_FAN_TOLERANCE / 100) - #self.min_fan_speed = FORWARD_FAN_F_SPEED * (1 - FORWARD_FAN_TOLERANCE / 100) else: self.std_fan_speed = FORWARD_FAN_R_SPEED - #self.max_fan_speed = FORWARD_FAN_R_SPEED * (1 + FORWARD_FAN_TOLERANCE / 100) - #self.min_fan_speed = FORWARD_FAN_R_SPEED * (1 - FORWARD_FAN_TOLERANCE / 100) - else: # this is a PSU Fan self.index = fan_index @@ -100,6 +93,7 @@ def _read_sysfs_file(self, sysfs_file): try: with open(sysfs_file, 'r') as fd: rv = fd.read() + fd.close() except Exception as e: rv = 'ERR' @@ -117,6 +111,7 @@ def _write_sysfs_file(self, sysfs_file, value): try: with open(sysfs_file, 'w') as fd: rv = fd.write(value) + fd.close() except Exception as e: rv = 'ERR' @@ -216,9 +211,9 @@ def get_direction(self): FAN_DIRECTION_EXHAUST depending on fan direction """ model_name = self.get_part_number() - if model_name[0:10] == "3HE16436AA": + if model_name[0:10] == FAN_PN_F2B: return self.FAN_DIRECTION_INTAKE - elif model_name[0:10] == "3HE16437AA": + elif model_name[0:10] == FAN_PN_B2F: return self.FAN_DIRECTION_EXHAUST else: return 'N/A' @@ -291,8 +286,20 @@ def set_speed(self, speed): if self.is_psu_fan: return False - if speed >= 0 and speed <= 100: - fandutycycle = round(float(speed)/100*255) + if speed in range(0, 10): + fandutycycle = 0x00 + elif speed in range(10, 21): + fandutycycle = 32 + elif speed in range(21, 31): + fandutycycle = 64 + elif speed in range(31, 46): + fandutycycle = 102 + elif speed in range(46, 61): + fandutycycle = 140 + elif speed in range(61, 81): + fandutycycle = 204 + elif speed in range(81, 101): + fandutycycle = 255 else: return False @@ -300,7 +307,7 @@ def set_speed(self, speed): if (rv != 'ERR'): return True else: - return False + return False def set_status_led(self, color): """ @@ -311,11 +318,10 @@ def set_status_led(self, color): Returns: bool: True if set success, False if fail. - off , red and green are the only settings 7215 fans + No indivial led for each H3 fans """ - return False - + def get_status_led(self): """ Gets the state of the fan status LED @@ -326,7 +332,7 @@ def get_status_led(self): if not self.get_presence(): return self.STATUS_LED_COLOR_OFF - file_str = SWPLD1_DIR + "fan{}_led".format(self.fan_drawer+1) + file_str = SWPLD1_DIR + "fan{}_led".format(self.drawer_index+1) result = self._read_sysfs_file(file_str) if result == '1': return self.STATUS_LED_COLOR_GREEN @@ -349,6 +355,20 @@ def get_target_speed(self): fan_duty = self._read_sysfs_file(self.set_fan_speed_reg) if (fan_duty != 'ERR'): - speed = round(float(fan_duty)/255*100) + dutyspeed = int(fan_duty) + if dutyspeed == 0: + speed = 0 + elif dutyspeed == 32: + speed = 15 + elif dutyspeed == 64: + speed = 25 + elif dutyspeed == 102: + speed = 40 + elif dutyspeed == 140: + speed = 50 + elif dutyspeed == 204: + speed = 70 + elif dutyspeed == 255: + speed = 100 return speed diff --git a/ixr7220h3/sonic_platform/fan_drawer.py b/ixr7220h3/sonic_platform/fan_drawer.py index 3683b4a..c89023f 100644 --- a/ixr7220h3/sonic_platform/fan_drawer.py +++ b/ixr7220h3/sonic_platform/fan_drawer.py @@ -7,24 +7,73 @@ ############################################################################# try: + import os + from sonic_platform.eeprom import Eeprom from sonic_platform_base.fan_drawer_base import FanDrawerBase from sonic_py_common import logger except ImportError as e: raise ImportError(str(e) + "- required module not found") +H3_FANS_PER_DRAWER = 2 +FAN_PN_F2B = "3HE16436AA" +FAN_PN_B2F = "3HE16437AA" +GPIO_DIR = "/sys/class/gpio/gpio{}/" +GPIO_PORT = [10224, 10225, 10226, 10227, 10228, 10229] +SWPLD1_DIR = "/sys/bus/i2c/devices/17-0032/" + sonic_logger = logger.Logger('fan_drawer') class NokiaFanDrawer(FanDrawerBase): def __init__(self, index): super(NokiaFanDrawer, self).__init__() - self._index = index + 1 - self._led = None + self._index = index + 1 + self.gpio_dir = GPIO_DIR.format(GPIO_PORT[index]) + self.system_led_supported_color = ['off', 'amber', 'green'] + self.eeprom = Eeprom(False, 0, True, index) + + def _read_sysfs_file(self, sysfs_file): + # On successful read, returns the value read from given + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'r') as fd: + rv = fd.read() + fd.close() + except Exception as e: + rv = 'ERR' + + rv = rv.rstrip('\r\n') + rv = rv.lstrip(" ") + return rv + + def _write_sysfs_file(self, sysfs_file, value): + # On successful write, the value read will be written on + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'w') as fd: + rv = fd.write(value) + fd.close() + except Exception as e: + rv = 'ERR' + + return rv def get_index(self): return self._index def get_presence(self): - return self._fan_list[0].get_presence() + result = self._read_sysfs_file(self.gpio_dir + 'value') + if result == '0': + return True + else: + return False def get_model(self): """ @@ -32,7 +81,7 @@ def get_model(self): Returns: string: Part number of Fan Drawer """ - return self._fan_list[0].get_model() + return self.eeprom.modelstr() def get_serial(self): """ @@ -40,7 +89,7 @@ def get_serial(self): Returns: string: Serial number of Fan """ - return self._fan_list[0].get_serial() + return self.eeprom.serial_number_str() def get_status(self): """ @@ -48,10 +97,31 @@ def get_status(self): Returns: bool: True if Fan is operating properly, False if not """ - return self._fan_list[0].get_status() + good_fan = 0 + for fan in self._fan_list: + if fan.get_status() == True: + good_fan = good_fan + 1 + + if (good_fan == H3_FANS_PER_DRAWER): + return True + else: + return False def get_direction(self): - return 'intake' + """ + Retrieves the fan airflow direction + Possible fan directions (relative to port-side of device) + Returns: + A string, either FAN_DIRECTION_INTAKE or + FAN_DIRECTION_EXHAUST depending on fan direction + """ + model_name = self.get_part_number() + if model_name[0:10] == FAN_PN_F2B: + return self.FAN_DIRECTION_INTAKE + elif model_name[0:10] == FAN_PN_B2F: + return self.FAN_DIRECTION_EXHAUST + else: + return 'N/A' def set_status_led(self, color): """ @@ -63,8 +133,29 @@ def set_status_led(self, color): Returns: bool: True if status LED state is set successfully, False if not + + off , amber and green are the only settings H3 fans """ - return self._fan_list[0].set_status_led(color) + if not self.get_presence(): + return False + if color not in self.system_led_supported_color: + return False + + if (color == 'off'): + value = '0' + elif (color == 'green'): + value = '1' + elif (color == 'amber'): + value = '2' + else: + return False + # Write sys led + status = self._write_sysfs_file(SWPLD1_DIR+"fan{}_led".format(self._index+1), value) + + if status == "ERR": + return False + + return True def get_status_led(self): """ @@ -73,7 +164,19 @@ def get_status_led(self): Returns: A string, one of the predefined STATUS_LED_COLOR_* strings """ - return self._fan_list[0].get_status_led() + if not self.get_presence(): + return self.STATUS_LED_COLOR_OFF + + file_str = SWPLD1_DIR + "fan{}_led".format(self._index+1) + result = self._read_sysfs_file(file_str) + if result == '1': + return self.STATUS_LED_COLOR_GREEN + elif result == '0': + return self.STATUS_LED_COLOR_OFF + elif result == '2': + return self.STATUS_LED_COLOR_RED + else: + return 'N/A' def is_replaceable(self): """ @@ -81,7 +184,7 @@ def is_replaceable(self): Returns: bool: True if it is replaceable. """ - return False + return True def get_position_in_parent(self): """ diff --git a/ixr7220h3/sonic_platform/platform.py b/ixr7220h3/sonic_platform/platform.py index 7a3046b..0af681c 100644 --- a/ixr7220h3/sonic_platform/platform.py +++ b/ixr7220h3/sonic_platform/platform.py @@ -11,12 +11,11 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") - class Platform(PlatformBase): """ Nokia platform-specific class """ def __init__(self): - PlatformBase.__init__(self) + PlatformBase.__init__(self) self._chassis = Chassis() diff --git a/ixr7220h3/sonic_platform/psu.py b/ixr7220h3/sonic_platform/psu.py index 3b9776f..b95f4b8 100644 --- a/ixr7220h3/sonic_platform/psu.py +++ b/ixr7220h3/sonic_platform/psu.py @@ -34,6 +34,8 @@ def __init__(self, psu_index): # PSU eeprom #self.eeprom = Eeprom(is_psu=True, psu_index=self.index) + self.MAX_VOLTAGE = 14 + self.MIN_VOLTAGE = 10 def _read_sysfs_file(self, sysfs_file): # On successful read, returns the value read from given @@ -45,6 +47,7 @@ def _read_sysfs_file(self, sysfs_file): try: with open(sysfs_file, 'r') as fd: rv = fd.read() + fd.close() except Exception as e: rv = 'ERR' @@ -62,6 +65,7 @@ def _write_sysfs_file(self, sysfs_file, value): try: with open(sysfs_file, 'w') as fd: rv = fd.write(value) + fd.close() except Exception as e: rv = 'ERR' @@ -241,6 +245,26 @@ def get_position_in_parent(self): """ return self.index + def get_voltage_high_threshold(self): + """ + Retrieves the high threshold PSU voltage output + + Returns: + A float number, the high threshold output voltage in volts, + e.g. 12.1 + """ + return self.MAX_VOLTAGE + + def get_voltage_low_threshold(self): + """ + Retrieves the low threshold PSU voltage output + + Returns: + A float number, the low threshold output voltage in volts, + e.g. 12.1 + """ + return self.MIN_VOLTAGE + def is_replaceable(self): """ Indicate whether this device is replaceable. diff --git a/ixr7220h3/sonic_platform/sfp.py b/ixr7220h3/sonic_platform/sfp.py index 2d36190..cc2bae8 100644 --- a/ixr7220h3/sonic_platform/sfp.py +++ b/ixr7220h3/sonic_platform/sfp.py @@ -11,7 +11,7 @@ import os import time from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase - from sonic_py_common.logger import Logger + from sonic_py_common import logger from sonic_py_common import device_info from sonic_py_common.general import getstatusoutput_noshell @@ -28,17 +28,15 @@ SWPLD2_DIR = "/sys/bus/i2c/devices/17-0034/" SWPLD3_DIR = "/sys/bus/i2c/devices/17-0035/" -# SFP PORT numbers - -logger = Logger() +SYSLOG_IDENTIFIER = "sfp" +sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) +sonic_logger.set_min_log_priority_info() class Sfp(SfpOptoeBase): """ Nokia IXR-7220 H3 Platform-specific Sfp refactor class """ instances = [] - - port_to_i2c_mapping = 0 def __init__(self, index, sfp_type, eeprom_path, port_i2c_map): SfpOptoeBase.__init__(self) @@ -57,11 +55,14 @@ def __init__(self, index, sfp_type, eeprom_path, port_i2c_map): self.port_name = sfp_type + '_' + str(index-QSFP_PORT_NUM-1) self.port_to_eeprom_mapping = {} self.port_to_eeprom_mapping[index] = eeprom_path + if self.index <= QSFP_IN_SWPLD: + self.swpld_path = SWPLD2_DIR + else: + self.swpld_path = SWPLD3_DIR self._version_info = device_info.get_sonic_version_info() - self.lastPresence = False - logger.log_debug("Sfp __init__ index {} setting name to {} and eeprom_path to {}".format(index, self.name, self.eeprom_path)) + #sonic_logger.log_info("Sfp __init__ index {} setting name to {} and eeprom_path to {}".format(index, self.name, self.eeprom_path)) Sfp.instances.append(self) @@ -75,6 +76,7 @@ def _read_sysfs_file(self, sysfs_file): try: with open(sysfs_file, 'r') as fd: rv = fd.read() + fd.close() except Exception as e: rv = 'ERR' @@ -91,6 +93,7 @@ def _write_sysfs_file(self, sysfs_file, value): try: with open(sysfs_file, 'w') as fd: rv = fd.write(value) + fd.close() except Exception as e: rv = 'ERR' @@ -105,15 +108,10 @@ def get_presence(self): Returns: bool: True if is present, False if not """ - if self.index <= QSFP_IN_SWPLD: - swpld_path = SWPLD2_DIR - else: - swpld_path = SWPLD3_DIR - if self.index <= QSFP_PORT_NUM: - sfpstatus = self._read_sysfs_file(swpld_path+"qsfp{}_prs".format(self.index)) + sfpstatus = self._read_sysfs_file(self.swpld_path+"qsfp{}_prs".format(self.index)) else: - sfpstatus = self._read_sysfs_file(swpld_path+"sfp{}_prs".format(self.index - QSFP_PORT_NUM - 1)) + sfpstatus = self._read_sysfs_file(self.swpld_path+"sfp{}_prs".format(self.index - QSFP_PORT_NUM - 1)) if sfpstatus == '0': return True @@ -178,8 +176,16 @@ def get_reset_status(self): Returns: A Boolean, True if reset enabled, False if disabled """ - return False - + if self.index <= QSFP_PORT_NUM: + result = self._read_sysfs_file(self.swpld_path+"qsfp{}_rstn".format(self.index)) + if result == '0': + return True + else: + return False + else: + return False + + def get_status(self): """ Retrieves the operational status of the device @@ -199,17 +205,33 @@ def reset(self): Returns: A boolean, True if successful, False if not """ + sonic_logger.log_info("Reseting port #{}.".format(self.index)) + result1 = 'ERR' result2 = 'ERR' - if self.index <= QSFP_IN_SWPLD: - swpld_path = SWPLD2_DIR - else: - swpld_path = SWPLD3_DIR + t = 0 if self.index <= QSFP_PORT_NUM: - result1 = self._write_sysfs_file(swpld_path+"qsfp{}_rstn".format(self.index), '0') - time.sleep(1) - result2 = self._write_sysfs_file(swpld_path+"qsfp{}_rstn".format(self.index), '1') + result2 = self._write_sysfs_file(self.swpld_path+"qsfp{}_reset".format(self.index), '1') + result2 = self._write_sysfs_file(self.swpld_path+"qsfp{}_lpmod".format(self.index), '1') + result1 = self._write_sysfs_file(self.swpld_path+"qsfp{}_rstn".format(self.index), '0') + time.sleep(0.5) + while t < 10: + if self._read_sysfs_file(self.swpld_path+"qsfp{}_reset".format(self.index)) == '2': + result1 = self._write_sysfs_file(self.swpld_path+"qsfp{}_rstn".format(self.index), '1') + time.sleep(2) + break + else: + time.sleep(0.5) + if t == 8: + sonic_logger.log_info("Reset port #{} timeout, reset failed.".format(self.index)) + return False + else: + t = t + 1 + + result2 = self._write_sysfs_file(self.swpld_path+"qsfp{}_reset".format(self.index), '3') + else: + return False if result1 != 'ERR' and result2 != 'ERR': return True @@ -225,17 +247,13 @@ def set_lpmode(self, lpmode): Returns: A boolean, True if lpmode is set successfully, False if not """ - result = 'ERR' - if self.index <= QSFP_IN_SWPLD: - swpld_path = SWPLD2_DIR - else: - swpld_path = SWPLD3_DIR + result = 'ERR' if self.index <= QSFP_PORT_NUM: if lpmode: - result = self._write_sysfs_file(swpld_path+"qsfp{}_lpmod".format(self.index), '1') + result = self._write_sysfs_file(self.swpld_path+"qsfp{}_lpmod".format(self.index), '1') else: - result = self._write_sysfs_file(swpld_path+"qsfp{}_lpmod".format(self.index), '0') + result = self._write_sysfs_file(self.swpld_path+"qsfp{}_lpmod".format(self.index), '0') if result != 'ERR': return True @@ -249,15 +267,15 @@ def get_lpmode(self): A Boolean, True if lpmode is enabled, False if disabled """ result = 'ERR' - if self.index <= QSFP_IN_SWPLD: - swpld_path = SWPLD2_DIR - else: - swpld_path = SWPLD3_DIR if self.index <= QSFP_PORT_NUM: - result = self._read_sysfs_file(swpld_path+"qsfp{}_lpmod".format(self.index)) + result = self._read_sysfs_file(self.swpld_path+"qsfp{}_lpmod".format(self.index)) if result == '1': return True return False + + + + diff --git a/ixr7220h3/sonic_platform/sfp_event.py b/ixr7220h3/sonic_platform/sfp_event.py index 1edcf1c..62d3341 100644 --- a/ixr7220h3/sonic_platform/sfp_event.py +++ b/ixr7220h3/sonic_platform/sfp_event.py @@ -19,16 +19,14 @@ SFP_PORT_NUM = 2 QSFP_IN_SWPLD = 16 -CPUPLD_DIR = "/sys/bus/i2c/devices/0-0031/" -SWPLD1_DIR = "/sys/bus/i2c/devices/17-0031/" SWPLD2_DIR = "/sys/bus/i2c/devices/17-0034/" SWPLD3_DIR = "/sys/bus/i2c/devices/17-0035/" SYSLOG_IDENTIFIER = "sfp_event" sonic_logger = logger.Logger(SYSLOG_IDENTIFIER) +sonic_logger.set_min_log_priority_info() - -class sfp_event: +class sfp_event(): ''' Listen to plugin/plugout cable events ''' def __init__(self): @@ -44,6 +42,7 @@ def _read_sysfs_file(self, sysfs_file): try: with open(sysfs_file, 'r') as fd: rv = fd.read() + fd.close() except Exception as e: rv = 'ERR' @@ -51,34 +50,71 @@ def _read_sysfs_file(self, sysfs_file): rv = rv.lstrip(" ") return rv + def _write_sysfs_file(self, sysfs_file, value): + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'w') as fd: + rv = fd.write(value) + fd.close() + except Exception as e: + rv = 'ERR' + + return rv + def initialize(self): self.modprs_list = [] # Get Transceiver status - time.sleep(5) + time.sleep(5) self.modprs_list = self._get_transceiver_status() + sonic_logger.log_info("Initial SFP presence=%s" % str(self.modprs_list)) def deinitialize(self): if self.handle is None: return - def _get_transceiver_status(self): - + def _get_transceiver_status(self): port_status = [] - for port in range (PORT_START, PORT_START + PORT_END): - if port <= QSFP_IN_SWPLD: - swpld_path = SWPLD2_DIR - else: - swpld_path = SWPLD3_DIR - if port <= QSFP_PORT_NUM: - status = self._read_sysfs_file(swpld_path+"qsfp{}_prs".format(port)) - else: - status = self._read_sysfs_file(swpld_path+"sfp{}_prs".format(port - QSFP_PORT_NUM - 1)) + reg_value = [] + reg_value.append(self._read_sysfs_file(SWPLD2_DIR + "modprs_reg1")) + reg_value.append(self._read_sysfs_file(SWPLD2_DIR + "modprs_reg2")) + reg_value.append(self._read_sysfs_file(SWPLD3_DIR + "modprs_reg1")) + reg_value.append(self._read_sysfs_file(SWPLD3_DIR + "modprs_reg2")) + for i in range(4): + bin_str = '{:08b}'.format(int(reg_value[i], 16)) + bool_list = [not bool(int(bit)) for bit in bin_str] + port_status.extend(bool_list) - if status == '0': - port_status.append(True) + for port in range (PORT_START, PORT_START + PORT_END): + if port <= QSFP_PORT_NUM: + if port_status[port-1]: + if port <= QSFP_IN_SWPLD: + swpld_path = SWPLD2_DIR + else: + swpld_path = SWPLD3_DIR + reset_status = self._read_sysfs_file(swpld_path+"qsfp{}_reset".format(port)) + if reset_status == '1': + sonic_logger.log_info("Port #%d is reseting... " % port) + port_status[port-1] = False + self._write_sysfs_file(swpld_path+"qsfp{}_reset".format(port), '2') + elif reset_status == '2': + sonic_logger.log_info("Port #%d is still reseting... " % port) + port_status[port-1] = False + elif reset_status == '3': + sonic_logger.log_info("Port #%d reset done... " % port) + port_status[port-1] = True + self._write_sysfs_file(swpld_path+"qsfp{}_reset".format(port), '0') + else: - port_status.append(False) + status = self._read_sysfs_file(SWPLD3_DIR+"sfp{}_prs".format(port - QSFP_PORT_NUM - 1)) + if status == '0': + port_status.append(True) + else: + port_status.append(False) return port_status @@ -86,7 +122,7 @@ def check_sfp_status(self, port_change, timeout): """ check_sfp_status called from get_change_event, this will return correct status of all SFP ports if there is a change in any of them - """ + """ start_time = time.time() forever = False diff --git a/ixr7220h3/sonic_platform/thermal.py b/ixr7220h3/sonic_platform/thermal.py index 12385a7..378725a 100644 --- a/ixr7220h3/sonic_platform/thermal.py +++ b/ixr7220h3/sonic_platform/thermal.py @@ -63,6 +63,7 @@ def _read_sysfs_file(self, sysfs_file): try: with open(sysfs_file, 'r') as fd: rv = fd.read() + fd.close() except Exception as e: rv = 'ERR' diff --git a/ixr7220h3/sonic_platform/watchdog.py b/ixr7220h3/sonic_platform/watchdog.py index cd74d69..f435f9d 100644 --- a/ixr7220h3/sonic_platform/watchdog.py +++ b/ixr7220h3/sonic_platform/watchdog.py @@ -4,59 +4,28 @@ """ import os -import fcntl -import array -import time +import sys from sonic_platform_base.watchdog_base import WatchdogBase -""" ioctl constants """ -IO_WRITE = 0x40000000 -IO_READ = 0x80000000 -IO_READ_WRITE = 0xC0000000 -IO_SIZE_INT = 0x00040000 -IO_TYPE_WATCHDOG = ord('W') << 8 - -WDR_INT = IO_READ | IO_SIZE_INT | IO_TYPE_WATCHDOG -WDWR_INT = IO_READ_WRITE | IO_SIZE_INT | IO_TYPE_WATCHDOG - -""" Watchdog ioctl commands """ -WDIOC_SETOPTIONS = 4 | WDR_INT -WDIOC_KEEPALIVE = 5 | WDR_INT -WDIOC_SETTIMEOUT = 6 | WDWR_INT -WDIOC_GETTIMEOUT = 7 | WDR_INT -WDIOC_SETPRETIMEOUT = 8 | WDWR_INT -WDIOC_GETPRETIMEOUT = 9 | WDR_INT -WDIOC_GETTIMELEFT = 10 | WDR_INT - -""" Watchdog status constants """ -WDIOS_DISABLECARD = 0x0001 -WDIOS_ENABLECARD = 0x0002 - """ watchdog sysfs """ -WD_SYSFS_PATH = "/sys/class/watchdog/watchdog0/" +WD_SYSFS_PATH = "/sys/bus/i2c/devices/0-0031/" WD_COMMON_ERROR = -1 - class WatchdogImplBase(WatchdogBase): """ Base class that implements common logic for interacting with watchdog using ioctl commands """ - def __init__(self, wd_device_path): + def __init__(self): """ Open a watchdog handle - @param wd_device_path Path to watchdog device """ super(WatchdogImplBase, self).__init__() - self.watchdog="" - self.watchdog_path = wd_device_path - self.wd_state_reg = WD_SYSFS_PATH+"state" - self.wd_timeout_reg = WD_SYSFS_PATH+"timeout" - self.wd_timeleft_reg = WD_SYSFS_PATH+"timeleft" - + #self.watchdog="" + self.wd_timeout_reg = WD_SYSFS_PATH+"wd_timer" self.timeout = self._gettimeout() def _read_sysfs_file(self, sysfs_file): @@ -69,47 +38,88 @@ def _read_sysfs_file(self, sysfs_file): try: with open(sysfs_file, 'r') as fd: rv = fd.read() + fd.close() except Exception as e: rv = 'ERR' rv = rv.rstrip('\r\n') rv = rv.lstrip(" ") return rv + + def _write_sysfs_file(self, sysfs_file, value): + # reg_name and on failure returns 'ERR' + rv = 'ERR' + + if (not os.path.isfile(sysfs_file)): + return rv + try: + with open(sysfs_file, 'w') as fd: + rv = fd.write(value) + fd.close() + except Exception as e: + rv = 'ERR' + + return rv def _disablewatchdog(self): """ Turn off the watchdog timer - """ - - req = array.array('h', [WDIOS_DISABLECARD]) - fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + """ + + self._write_sysfs_file(WD_SYSFS_PATH+"wd_enable", '0') def _enablewatchdog(self): """ Turn on the watchdog timer """ - req = array.array('h', [WDIOS_ENABLECARD]) - fcntl.ioctl(self.watchdog, WDIOC_SETOPTIONS, req, False) + self._write_sysfs_file(WD_SYSFS_PATH+"wd_enable", '1') def _keepalive(self): """ Keep alive watchdog timer """ - fcntl.ioctl(self.watchdog, WDIOC_KEEPALIVE) + self._write_sysfs_file(WD_SYSFS_PATH+"wd_punch", '0') def _settimeout(self, seconds): """ Set watchdog timer timeout @param seconds - timeout in seconds @return is the actual set timeout - """ - - req = array.array('I', [seconds]) - fcntl.ioctl(self.watchdog, WDIOC_SETTIMEOUT, req, True) + """ + + if seconds in range(0, 16): + timeout = 15 + reg_value = '0' + elif seconds in range(16, 21): + timeout = 20 + reg_value = '1' + elif seconds in range(21, 31): + timeout = 30 + reg_value = '2' + elif seconds in range(31, 41): + timeout = 40 + reg_value = '3' + elif seconds in range(41, 51): + timeout = 50 + reg_value = '4' + elif seconds in range(51, 61): + timeout = 60 + reg_value = '5' + elif seconds in range(61, 66): + timeout = 65 + reg_value = '6' + elif seconds in range(67, 71): + timeout = 70 + reg_value = '7' + else: + timeout = 30 + reg_value = '2' + + self._write_sysfs_file(self.wd_timeout_reg, reg_value) - return int(req[0]) + return timeout def _gettimeout(self): """ @@ -117,7 +127,8 @@ def _gettimeout(self): @return watchdog timeout """ timeout=0 - timeout=self._read_sysfs_file(self.wd_timeout_reg) + reg_value = self._read_sysfs_file(self.wd_timeout_reg) + timeout = int(reg_value[5:7]) return timeout @@ -127,26 +138,20 @@ def _gettimeleft(self): @return time left in seconds """ - req = array.array('I', [0]) - fcntl.ioctl(self.watchdog, WDIOC_GETTIMELEFT, req, True) - - return int(req[0]) - + # H3 platform do not support this feature + return WD_COMMON_ERROR + def arm(self, seconds): """ Arm the hardware watchdog """ ret = WD_COMMON_ERROR - if seconds < 0 or seconds >= 350: - return ret + if seconds < 0 or seconds > 70: + sys.stderr.write("Error: Wrong watchdog timer choice: {} \n".format(seconds)) + sys.stderr.write("H3 platform only support watchdog timer in [15, 20, 30, 40, 50, 60, 65, 70] seconds\n\n") + return ret - # Stop the watchdog service to gain access of watchdog file pointer - # if self.is_armed(): - # os.popen("systemctl stop cpu_wdt.service") - # time.sleep(2) - if not self.watchdog: - self.watchdog = os.open(self.watchdog_path, os.O_WRONLY) try: if self.timeout != seconds: self.timeout = self._settimeout(seconds) @@ -169,11 +174,7 @@ def disarm(self): if not """ - if self.is_armed(): - #os.popen("systemctl stop cpu_wdt.service") - #time.sleep(2) - if not self.watchdog: - self.watchdog = os.open(self.watchdog_path, os.O_WRONLY) + if self.is_armed(): try: self._disablewatchdog() self.timeout = 0 @@ -188,8 +189,8 @@ def is_armed(self): """ status = False - state = self._read_sysfs_file(self.wd_state_reg) - if (state != 'inactive'): + state = self._read_sysfs_file(WD_SYSFS_PATH+"wd_enable") + if state == '1': status = True return status @@ -198,10 +199,5 @@ def get_remaining_time(self): """ Implements get_remaining_time WatchdogBase API """ - - timeleft = WD_COMMON_ERROR - - if self.is_armed(): - timeleft=self._read_sysfs_file(self.wd_timeleft_reg) - - return int(timeleft) + # H3 platform do not support this feature + return WD_COMMON_ERROR \ No newline at end of file