From 7302132103cdf357c0d40341df3ab3e7361fd1d1 Mon Sep 17 00:00:00 2001 From: Jemston Fernando Date: Thu, 30 Nov 2023 17:27:48 +0000 Subject: [PATCH 1/3] Fix for Celestica platform issue and new WB support - Support for new platform Questone - Belgite renamed to DS1000 - Hardened bug fixes and unified CLI O/P for Celestica platforms --- .../CELESTICA-BELGITE/port_config.ini | 57 - .../CELESTICA-BELGITE/sai.profile | 1 - .../x86_64-cel_belgite-r0/custom_led.bin | Bin 220 -> 0 bytes .../x86_64-cel_belgite-r0/default_sku | 1 - .../pddf/pddf-device.json.original | 686 ----- .../platform_components.json | 10 - .../DS1000/ds1000.config.bcm} | 0 .../DS1000}/hwsku.json | 0 .../DS1000/port_config.ini | 57 + .../x86_64-cel_ds1000-r0/DS1000/sai.profile | 1 + .../x86_64-cel_ds1000-r0/custom_led.bin | Bin 0 -> 272 bytes .../x86_64-cel_ds1000-r0/default_sku | 1 + .../installer.conf | 4 +- .../led-source-code/cmicx/Makefile | 0 .../led-source-code/cmicx/custom_led.c | 66 +- .../led-source-code/cmicx/custom_led.lds | 0 .../led_proc_init.soc | 0 .../media_settings.json | 0 .../pcie.yaml | 108 +- .../pddf/pd-plugin.json | 4 +- .../pddf/pddf-device.json | 79 +- .../pddf_support | 0 .../platform.json | 358 +-- .../platform_asic | 0 .../platform_components.json | 12 + .../x86_64-cel_ds1000-r0/platform_reboot | 3 + .../plugins/eeprom.py | 0 .../plugins/psuutil.py | 0 .../plugins/sfputil.py | 0 .../pmon_daemon_control.json | 0 .../x86_64-cel_ds1000-r0/sensors.conf | 45 + .../system_health_monitoring_config.json | 4 +- .../Questone_2/custom_led.bin | Bin 0 -> 248 bytes .../Questone_2/hwsku.json | 284 +++ .../Questone_2/platform.json | 396 +++ .../Questone_2/platform_components.json | 17 + .../Questone_2/port_config.ini | 57 + .../Questone_2/sai.profile | 1 + .../Questone_2/td3-as13-48f8h.config.bcm | 357 +++ .../Questone_2A/custom_led.bin | Bin 0 -> 308 bytes .../Questone_2A/hwsku.json | 284 +++ .../Questone_2A/platform.json | 396 +++ .../Questone_2A/platform_components.json | 17 + .../Questone_2A/port_config.ini | 57 + .../Questone_2A/sai.profile.j2 | 16 + .../td3-as13-48f8h-vxlan.config.bcm | 423 ++++ .../Questone_2A/td3-as13-48f8h.config.bcm | 412 +++ .../x86_64-cel_questone_2-r0/installer.conf | 4 + .../led_proc_init.soc | 8 + .../opennsl-postinit.cfg | 3 + .../x86_64-cel_questone_2-r0/pcie.yaml | 153 ++ .../x86_64-cel_questone_2-r0/platform_asic | 1 + .../x86_64-cel_questone_2-r0/platform_reboot | 6 + .../plugins/eeprom.py | 23 + .../plugins/sfputil.py | 312 +++ .../pmon_daemon_control.json | 5 + .../system_health_monitoring_config.json | 13 + .../warm-reboot_plugin | 4 + .../Seastone_2/buffers.json.j2 | 2 + .../Seastone_2/buffers_defaults_def.j2 | 46 + .../Seastone_2/buffers_defaults_t0.j2 | 45 + .../Seastone_2/buffers_defaults_t1.j2 | 46 + .../Seastone_2/hwsku.json | 169 ++ .../Seastone_2/l2/config | 3 + .../Seastone_2/l3/config | 3 + .../Seastone_2/pg_profile_lookup.ini | 17 + .../Seastone_2/port_config.ini | 68 +- .../Seastone_2/qos.json.j2 | 1 + .../Seastone_2/sai.profile | 2 - .../Seastone_2/sai.profile.j2 | 17 + .../td3-seastone_2-32x100G-vxlan.config.bcm | 576 +++++ .../td3-seastone_2-32x100G.config.bcm | 127 +- .../{custom.bin => custom_led.bin} | Bin .../x86_64-cel_seastone_2-r0/installer.conf | 3 +- .../led_proc_init.soc | 5 +- .../x86_64-cel_seastone_2-r0/pcie.yaml | 153 ++ .../x86_64-cel_seastone_2-r0/platform.json | 235 ++ .../platform_components.json | 17 + .../x86_64-cel_seastone_2-r0/platform_reboot | 6 + .../plugins/psuutil.py | 25 +- .../pmon_daemon_control.json | 8 +- .../sonic_platform_config/chassis.json | 45 - .../sonic_platform_config/component.json | 62 - .../sonic_platform_config/event.py | 117 - .../sonic_platform_config/fan.json | 200 -- .../sonic_platform_config/psu.json | 135 - .../sonic_platform_config/sfp.json | 143 -- .../sonic_platform_config/thermal.json | 105 - .../sonic_platform_config/watchdog.py | 191 -- .../system_health_monitoring_config.json | 13 + .../warm-reboot_plugin | 4 + .../th3-128x100G.config.bcm | 4 - .../Silverstone/hwsku.json | 164 ++ .../Silverstone/port_config.ini | 64 +- .../Silverstone/th3-32x400G.config.bcm | 68 +- .../x86_64-cel_silverstone-r0/pcie.yaml | 434 ++++ .../x86_64-cel_silverstone-r0/platform.json | 484 ++++ .../platform_components.json | 18 + .../x86_64-cel_silverstone-r0/platform_reboot | 6 + .../plugins/psuutil.py | 11 +- .../pmon_daemon_control.json | 4 +- .../sonic_platform/__init__.py | 2 - .../sonic_platform/chassis.py | 131 - .../sonic_platform/component.py | 118 - .../sonic_platform/eeprom.py | 117 - .../sonic_platform/helper.py | 111 - .../sonic_platform/psu.py | 236 -- .../sonic_platform/sfp.py | 1467 ----------- .../system_health_monitoring_config.json | 13 + .../warm-reboot_plugin | 4 + platform/broadcom/one-image.mk | 3 +- platform/broadcom/platform-modules-cel.mk | 24 +- .../belgite/pddf/sonic_platform/__init__.py | 4 - .../belgite/pddf/sonic_platform/fan.py | 93 - .../belgite/pddf/sonic_platform/sfp.py | 15 - .../belgite/pddf/sonic_platform/thermal.py | 111 - .../scripts/pddf_post_device_create.sh | 13 - .../belgite-pddf-platform-monitor.service | 16 - .../belgite/utils/belgite_pddf_monitor.py | 272 -- .../debian/changelog | 8 + .../sonic-platform-modules-cel/debian/control | 7 +- .../debian/platform-modules-belgite.install | 7 - .../debian/platform-modules-ds1000.install | 8 + ...tinst => platform-modules-ds1000.postinst} | 4 +- .../debian/platform-modules-dx010.init | 8 +- .../debian/platform-modules-haliburton.init | 9 + .../debian/platform-modules-questone2.install | 10 + .../platform-modules-questone2.postinst | 6 + .../debian/platform-modules-seastone2.init | 25 +- .../debian/platform-modules-seastone2.install | 3 + .../platform-modules-seastone2.postinst | 5 +- .../debian/platform-modules-silverstone.init | 89 +- .../platform-modules-silverstone.install | 1 + .../platform-modules-silverstone.postinst | 5 +- .../sonic-platform-modules-cel/debian/rules | 27 +- .../{belgite => ds1000}/modules/Makefile | 0 .../{belgite => ds1000}/modules/mc24lc64t.c | 0 .../modules/pddf_custom_psu.c | 0 .../modules/pddf_custom_wdt.c | 29 +- .../{belgite => ds1000}/pddf/setup.py | 2 +- .../ds1000/pddf/sonic_platform/__init__.py | 2 + .../pddf/sonic_platform/chassis.py | 86 +- .../pddf/sonic_platform/component.py | 82 +- .../pddf/sonic_platform/eeprom.py | 13 +- .../ds1000/pddf/sonic_platform/fan.py | 134 + .../pddf/sonic_platform/fan_drawer.py | 3 + .../ds1000/pddf/sonic_platform/pcie.py | 15 + .../pddf/sonic_platform/platform.py | 0 .../pddf/sonic_platform/psu.py | 35 + .../ds1000/pddf/sonic_platform/sfp.py | 36 + .../ds1000/pddf/sonic_platform/thermal.py | 105 + .../pddf/sonic_platform/watchdog.py | 0 .../scripts/ds1000_platform_shutdown.sh | 26 + .../ds1000/scripts/pddf_post_device_create.sh | 22 + .../scripts/pddf_pre_driver_install.sh | 0 .../ds1000/service/ds1000-fan-control.service | 17 + .../systemd/pddf-platform-init.service | 2 +- .../ds1000/utils/ds1000_fanctld.py | 346 +++ .../questone2/cfg/pid_config_questone2.ini | 19 + .../questone2/cfg/questone2-modprobe.conf | 1 + .../questone2/cfg/questone2-modules.conf | 16 + .../questone2/modules/Makefile | 1 + .../questone2/modules/mc24lc64t.c | 173 ++ .../questone2/modules/optoe.c | 1147 +++++++++ .../modules/questone2_baseboard_cpld.c | 409 +++ .../questone2/modules/questone2_switchboard.c | 2211 +++++++++++++++++ .../questone2/modules/sff-8436.h | 31 + .../questone2/modules/sff_8436_eeprom.c | 982 ++++++++ .../questone2/scripts/platform_sensors.py | 161 ++ .../scripts/questone2_platform_shutdown.sh | 26 + .../questone2/scripts/sensors | 11 + .../questone2/setup.py | 10 + .../questone2/sonic_platform/__init__.py | 2 + .../questone2/sonic_platform/chassis.py | 441 ++++ .../questone2/sonic_platform/component.py | 156 ++ .../questone2/sonic_platform/eeprom.py | 128 + .../questone2/sonic_platform/fan.py | 345 +++ .../questone2/sonic_platform/fan_drawer.py | 82 + .../questone2/sonic_platform/helper.py | 210 ++ .../questone2/sonic_platform/pcie.py | 15 + .../questone2/sonic_platform/platform.py | 23 + .../questone2/sonic_platform/psu.py | 265 ++ .../questone2/sonic_platform/sfp.py | 197 ++ .../questone2}/sonic_platform/thermal.py | 132 +- .../questone2/sonic_platform/watchdog.py | 268 ++ .../platform-modules-questone2.service | 13 + .../seastone2/scripts/platform_sensors.py | 161 ++ .../scripts/seastone2_platform_shutdown.sh | 26 + .../seastone2/scripts/sensors | 11 + .../seastone2/setup.py | 31 + .../seastone2/sonic_platform/__init__.py | 2 + .../seastone2/sonic_platform/chassis.py | 436 ++++ .../seastone2/sonic_platform/component.py | 156 ++ .../seastone2/sonic_platform/eeprom.py | 128 + .../seastone2/sonic_platform/fan.py | 345 +++ .../seastone2/sonic_platform/fan_drawer.py | 91 + .../seastone2/sonic_platform/helper.py | 210 ++ .../seastone2/sonic_platform/pcie.py | 15 + .../seastone2/sonic_platform/platform.py | 23 + .../seastone2/sonic_platform/psu.py | 273 ++ .../seastone2/sonic_platform/sfp.py | 198 ++ .../seastone2/sonic_platform/thermal.py | 204 ++ .../seastone2/sonic_platform/watchdog.py | 274 ++ .../silverstone/cfg/silverstone-modules.conf | 4 +- .../silverstone/modules/Makefile | 2 +- .../silverstone/modules/baseboard-lpc.c | 4 +- .../silverstone/modules/cls-i2c-mux-pca954x.c | 579 +++++ .../silverstone/modules/cls-pca954x.h | 44 + .../silverstone/modules/cls-switchboard.c | 542 ++++ .../silverstone/modules/switch_cpld.c | 417 ++++ .../silverstone/modules/switchboard.c | 2106 ---------------- .../silverstone/modules/xcvr-cls.c | 520 ++++ .../silverstone/modules/xcvr-cls.h | 41 + .../silverstone/scripts/platform_sensors.py | 112 +- .../silverstone/scripts/sensors | 2 +- .../scripts/silverstone_platform_shutdown.sh | 26 + .../silverstone/setup.py | 5 +- .../silverstone/sonic_platform/__init__.py | 2 + .../silverstone/sonic_platform/chassis.py | 436 ++++ .../silverstone/sonic_platform/component.py | 182 ++ .../silverstone/sonic_platform/eeprom.py | 123 + .../silverstone}/sonic_platform/fan.py | 234 +- .../silverstone/sonic_platform/fan_drawer.py | 108 + .../silverstone/sonic_platform/helper.py | 197 ++ .../silverstone/sonic_platform/pcie.py | 15 + .../silverstone}/sonic_platform/platform.py | 0 .../silverstone/sonic_platform/psu.py | 332 +++ .../silverstone/sonic_platform/sfp.py | 232 ++ .../silverstone/sonic_platform/thermal.py | 205 ++ .../sonic_platform/thermal_manager.py | 21 + .../silverstone/sonic_platform/watchdog.py | 247 ++ 231 files changed, 21844 insertions(+), 7472 deletions(-) delete mode 100644 device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/port_config.ini delete mode 100644 device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/sai.profile delete mode 100644 device/celestica/x86_64-cel_belgite-r0/custom_led.bin delete mode 100644 device/celestica/x86_64-cel_belgite-r0/default_sku delete mode 100644 device/celestica/x86_64-cel_belgite-r0/pddf/pddf-device.json.original delete mode 100644 device/celestica/x86_64-cel_belgite-r0/platform_components.json rename device/celestica/{x86_64-cel_belgite-r0/CELESTICA-BELGITE/belgite.config.bcm => x86_64-cel_ds1000-r0/DS1000/ds1000.config.bcm} (100%) rename device/celestica/{x86_64-cel_belgite-r0/CELESTICA-BELGITE => x86_64-cel_ds1000-r0/DS1000}/hwsku.json (100%) create mode 100644 device/celestica/x86_64-cel_ds1000-r0/DS1000/port_config.ini create mode 100644 device/celestica/x86_64-cel_ds1000-r0/DS1000/sai.profile create mode 100755 device/celestica/x86_64-cel_ds1000-r0/custom_led.bin create mode 100644 device/celestica/x86_64-cel_ds1000-r0/default_sku rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/installer.conf (83%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/led-source-code/cmicx/Makefile (100%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/led-source-code/cmicx/custom_led.c (81%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/led-source-code/cmicx/custom_led.lds (100%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/led_proc_init.soc (100%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/media_settings.json (100%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/pcie.yaml (56%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/pddf/pd-plugin.json (89%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/pddf/pddf-device.json (87%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/pddf_support (100%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/platform.json (62%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/platform_asic (100%) create mode 100644 device/celestica/x86_64-cel_ds1000-r0/platform_components.json create mode 100755 device/celestica/x86_64-cel_ds1000-r0/platform_reboot rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/plugins/eeprom.py (100%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/plugins/psuutil.py (100%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/plugins/sfputil.py (100%) rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/pmon_daemon_control.json (100%) create mode 100644 device/celestica/x86_64-cel_ds1000-r0/sensors.conf rename device/celestica/{x86_64-cel_belgite-r0 => x86_64-cel_ds1000-r0}/system_health_monitoring_config.json (86%) create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2/custom_led.bin create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2/hwsku.json create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2/platform.json create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2/platform_components.json create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2/port_config.ini create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2/sai.profile create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2/td3-as13-48f8h.config.bcm create mode 100755 device/celestica/x86_64-cel_questone_2-r0/Questone_2A/custom_led.bin create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2A/hwsku.json create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2A/platform.json create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2A/platform_components.json create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2A/port_config.ini create mode 100644 device/celestica/x86_64-cel_questone_2-r0/Questone_2A/sai.profile.j2 create mode 100755 device/celestica/x86_64-cel_questone_2-r0/Questone_2A/td3-as13-48f8h-vxlan.config.bcm create mode 100755 device/celestica/x86_64-cel_questone_2-r0/Questone_2A/td3-as13-48f8h.config.bcm create mode 100644 device/celestica/x86_64-cel_questone_2-r0/installer.conf create mode 100644 device/celestica/x86_64-cel_questone_2-r0/led_proc_init.soc create mode 100644 device/celestica/x86_64-cel_questone_2-r0/opennsl-postinit.cfg create mode 100644 device/celestica/x86_64-cel_questone_2-r0/pcie.yaml create mode 100644 device/celestica/x86_64-cel_questone_2-r0/platform_asic create mode 100755 device/celestica/x86_64-cel_questone_2-r0/platform_reboot create mode 100644 device/celestica/x86_64-cel_questone_2-r0/plugins/eeprom.py create mode 100755 device/celestica/x86_64-cel_questone_2-r0/plugins/sfputil.py create mode 100644 device/celestica/x86_64-cel_questone_2-r0/pmon_daemon_control.json create mode 100644 device/celestica/x86_64-cel_questone_2-r0/system_health_monitoring_config.json create mode 100755 device/celestica/x86_64-cel_questone_2-r0/warm-reboot_plugin create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers.json.j2 create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_def.j2 create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_t0.j2 create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_t1.j2 create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/hwsku.json create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/l2/config create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/l3/config create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/pg_profile_lookup.ini create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/qos.json.j2 delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile.j2 create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G-vxlan.config.bcm rename device/celestica/x86_64-cel_seastone_2-r0/{custom.bin => custom_led.bin} (100%) create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/pcie.yaml create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/platform.json create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/platform_components.json create mode 100755 device/celestica/x86_64-cel_seastone_2-r0/platform_reboot delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json delete mode 100644 device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py create mode 100644 device/celestica/x86_64-cel_seastone_2-r0/system_health_monitoring_config.json create mode 100755 device/celestica/x86_64-cel_seastone_2-r0/warm-reboot_plugin create mode 100644 device/celestica/x86_64-cel_silverstone-r0/Silverstone/hwsku.json create mode 100644 device/celestica/x86_64-cel_silverstone-r0/pcie.yaml create mode 100644 device/celestica/x86_64-cel_silverstone-r0/platform.json create mode 100644 device/celestica/x86_64-cel_silverstone-r0/platform_components.json create mode 100755 device/celestica/x86_64-cel_silverstone-r0/platform_reboot delete mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py delete mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py delete mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py delete mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py delete mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py delete mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py delete mode 100644 device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py create mode 100644 device/celestica/x86_64-cel_silverstone-r0/system_health_monitoring_config.json create mode 100755 device/celestica/x86_64-cel_silverstone-r0/warm-reboot_plugin delete mode 100644 platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/__init__.py delete mode 100644 platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/fan.py delete mode 100644 platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/sfp.py delete mode 100644 platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/thermal.py delete mode 100755 platform/broadcom/sonic-platform-modules-cel/belgite/scripts/pddf_post_device_create.sh delete mode 100644 platform/broadcom/sonic-platform-modules-cel/belgite/service/belgite-pddf-platform-monitor.service delete mode 100755 platform/broadcom/sonic-platform-modules-cel/belgite/utils/belgite_pddf_monitor.py delete mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-belgite.install create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds1000.install rename platform/broadcom/sonic-platform-modules-cel/debian/{platform-modules-belgite.postinst => platform-modules-ds1000.postinst} (56%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.install create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.postinst rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/modules/Makefile (100%) rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/modules/mc24lc64t.c (100%) rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/modules/pddf_custom_psu.c (100%) rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/modules/pddf_custom_wdt.c (96%) rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/pddf/setup.py (94%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/__init__.py rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/pddf/sonic_platform/chassis.py (72%) rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/pddf/sonic_platform/component.py (50%) rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/pddf/sonic_platform/eeprom.py (83%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/fan.py rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/pddf/sonic_platform/fan_drawer.py (92%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/pcie.py rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/pddf/sonic_platform/platform.py (100%) rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/pddf/sonic_platform/psu.py (61%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/thermal.py rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/pddf/sonic_platform/watchdog.py (100%) create mode 100755 platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/ds1000_platform_shutdown.sh create mode 100755 platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/pddf_post_device_create.sh rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/scripts/pddf_pre_driver_install.sh (100%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/ds1000/service/ds1000-fan-control.service rename platform/broadcom/sonic-platform-modules-cel/{belgite => ds1000}/systemd/pddf-platform-init.service (81%) create mode 100755 platform/broadcom/sonic-platform-modules-cel/ds1000/utils/ds1000_fanctld.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/cfg/pid_config_questone2.ini create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/cfg/questone2-modprobe.conf create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/cfg/questone2-modules.conf create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/modules/Makefile create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/modules/mc24lc64t.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/modules/optoe.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/modules/questone2_baseboard_cpld.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/modules/questone2_switchboard.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff-8436.h create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff_8436_eeprom.c create mode 100755 platform/broadcom/sonic-platform-modules-cel/questone2/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-cel/questone2/scripts/questone2_platform_shutdown.sh create mode 100755 platform/broadcom/sonic-platform-modules-cel/questone2/scripts/sensors create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/helper.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/pcie.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/sfp.py rename {device/celestica/x86_64-cel_silverstone-r0 => platform/broadcom/sonic-platform-modules-cel/questone2}/sonic_platform/thermal.py (50%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/watchdog.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/questone2/systemd/platform-modules-questone2.service create mode 100755 platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/platform_sensors.py create mode 100755 platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/seastone2_platform_shutdown.sh create mode 100755 platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/sensors create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/setup.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/eeprom.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/fan.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/helper.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/pcie.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/platform.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/thermal.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/watchdog.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-i2c-mux-pca954x.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-pca954x.h create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-switchboard.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switch_cpld.c delete mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/xcvr-cls.c create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/modules/xcvr-cls.h create mode 100755 platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/silverstone_platform_shutdown.sh create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/__init__.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/chassis.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/component.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/eeprom.py rename {device/celestica/x86_64-cel_silverstone-r0 => platform/broadcom/sonic-platform-modules-cel/silverstone}/sonic_platform/fan.py (51%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/fan_drawer.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/helper.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/pcie.py rename {device/celestica/x86_64-cel_silverstone-r0 => platform/broadcom/sonic-platform-modules-cel/silverstone}/sonic_platform/platform.py (100%) create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/psu.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/sfp.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/thermal.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/thermal_manager.py create mode 100644 platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/watchdog.py diff --git a/device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/port_config.ini b/device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/port_config.ini deleted file mode 100644 index 90ecfa4859..0000000000 --- a/device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/port_config.ini +++ /dev/null @@ -1,57 +0,0 @@ -# name lanes alias index speed autoneg -Ethernet0 26 Ethernet1/0/1 1 1000 1 -Ethernet1 25 Ethernet1/0/2 2 1000 1 -Ethernet2 28 Ethernet1/0/3 3 1000 1 -Ethernet3 27 Ethernet1/0/4 4 1000 1 -Ethernet4 30 Ethernet1/0/5 5 1000 1 -Ethernet5 29 Ethernet1/0/6 6 1000 1 -Ethernet6 32 Ethernet1/0/7 7 1000 1 -Ethernet7 31 Ethernet1/0/8 8 1000 1 -Ethernet8 34 Ethernet1/0/9 9 1000 1 -Ethernet9 33 Ethernet1/0/10 10 1000 1 -Ethernet10 36 Ethernet1/0/11 11 1000 1 -Ethernet11 35 Ethernet1/0/12 12 1000 1 -Ethernet12 38 Ethernet1/0/13 13 1000 1 -Ethernet13 37 Ethernet1/0/14 14 1000 1 -Ethernet14 40 Ethernet1/0/15 15 1000 1 -Ethernet15 39 Ethernet1/0/16 16 1000 1 -Ethernet16 42 Ethernet1/0/17 17 1000 1 -Ethernet17 41 Ethernet1/0/18 18 1000 1 -Ethernet18 44 Ethernet1/0/19 19 1000 1 -Ethernet19 43 Ethernet1/0/20 20 1000 1 -Ethernet20 50 Ethernet1/0/21 21 1000 1 -Ethernet21 49 Ethernet1/0/22 22 1000 1 -Ethernet22 52 Ethernet1/0/23 23 1000 1 -Ethernet23 51 Ethernet1/0/24 24 1000 1 -Ethernet24 2 Ethernet1/0/25 25 1000 1 -Ethernet25 1 Ethernet1/0/26 26 1000 1 -Ethernet26 4 Ethernet1/0/27 27 1000 1 -Ethernet27 3 Ethernet1/0/28 28 1000 1 -Ethernet28 6 Ethernet1/0/29 29 1000 1 -Ethernet29 5 Ethernet1/0/30 30 1000 1 -Ethernet30 8 Ethernet1/0/31 31 1000 1 -Ethernet31 7 Ethernet1/0/32 32 1000 1 -Ethernet32 10 Ethernet1/0/33 33 1000 1 -Ethernet33 9 Ethernet1/0/34 34 1000 1 -Ethernet34 12 Ethernet1/0/35 35 1000 1 -Ethernet35 11 Ethernet1/0/36 36 1000 1 -Ethernet36 14 Ethernet1/0/37 37 1000 1 -Ethernet37 13 Ethernet1/0/38 38 1000 1 -Ethernet38 16 Ethernet1/0/39 39 1000 1 -Ethernet39 15 Ethernet1/0/40 40 1000 1 -Ethernet40 18 Ethernet1/0/41 41 1000 1 -Ethernet41 17 Ethernet1/0/42 42 1000 1 -Ethernet42 20 Ethernet1/0/43 43 1000 1 -Ethernet43 19 Ethernet1/0/44 44 1000 1 -Ethernet44 22 Ethernet1/0/45 45 1000 1 -Ethernet45 21 Ethernet1/0/46 46 1000 1 -Ethernet46 24 Ethernet1/0/47 47 1000 1 -Ethernet47 23 Ethernet1/0/48 48 1000 1 -Ethernet48 60 Ethernet1/0/49 49 10000 0 -Ethernet49 58 Ethernet1/0/50 50 10000 0 -Ethernet50 59 Ethernet1/0/51 51 10000 0 -Ethernet51 57 Ethernet1/0/52 52 10000 0 -Ethernet52 62 Ethernet1/0/53 53 10000 0 -Ethernet53 64 Ethernet1/0/54 54 10000 0 -Ethernet54 61 Ethernet1/0/55 55 10000 0 -Ethernet55 63 Ethernet1/0/56 56 10000 0 diff --git a/device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/sai.profile b/device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/sai.profile deleted file mode 100644 index 2e5979fd11..0000000000 --- a/device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/sai.profile +++ /dev/null @@ -1 +0,0 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/belgite.config.bcm diff --git a/device/celestica/x86_64-cel_belgite-r0/custom_led.bin b/device/celestica/x86_64-cel_belgite-r0/custom_led.bin deleted file mode 100644 index c1b5e0e1b1d6df0a03d57ba312715b5ebb0b772e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 220 zcmV~$yH3JT0D$4YEecYRn<6MEP>_oz1jHLvEG0RED-*D2F_FQ6Cm@80MK KSJbh%;g)~zw=1~- diff --git a/device/celestica/x86_64-cel_belgite-r0/default_sku b/device/celestica/x86_64-cel_belgite-r0/default_sku deleted file mode 100644 index 3eeb370889..0000000000 --- a/device/celestica/x86_64-cel_belgite-r0/default_sku +++ /dev/null @@ -1 +0,0 @@ -CELESTICA-BELGITE t1 diff --git a/device/celestica/x86_64-cel_belgite-r0/pddf/pddf-device.json.original b/device/celestica/x86_64-cel_belgite-r0/pddf/pddf-device.json.original deleted file mode 100644 index 8f43a3f609..0000000000 --- a/device/celestica/x86_64-cel_belgite-r0/pddf/pddf-device.json.original +++ /dev/null @@ -1,686 +0,0 @@ -{ - "PLATFORM": - { - "num_psus":2, - "num_fantrays":3, - "num_fans_pertray":1, - "num_ports":56, - "num_temps":4, - "pddf_dev_types": - { - "description":"Belgite - Below is the list of supported PDDF device types (chip names) for various components. If any component uses some other driver, we will create the client using 'echo > /new_device' method", - "CPLD": - [ - "i2c_cpld" - ], - "PSU": - [ - "psu_eeprom", - "psu_pmbus" - ], - "FAN": - [ - "fan_ctrl", - "fan_eeprom", - "fan_cpld" - ], - "PORT_MODULE": - [ - "pddf_xcvr" - ] - }, - "std_perm_kos": - [ - "i2c-ismt", - "i2c-i801" - ], - "std_kos": - [ - "i2c_dev", - "i2c_mux_pca954x", - "gpio_pca953x", - "mc24lc64t", - "optoe" - ], - "pddf_kos": - [ - "pddf_client_module", - "pddf_mux_module", - "pddf_psu_driver_module", - "pddf_psu_module", - "pddf_gpio_module", - "pddf_xcvr_module", - "pddf_xcvr_driver_module", - "pddf_led_module", - "pddf_fan_driver_module", - "pddf_fan_module", - "pddf_led_module" - ], - "custom_kos": - [ - "pddf_custom_psu" - ] - }, - "SYSTEM": - { - "dev_info": {"device_type":"CPU", "device_name":"ROOT_COMPLEX", "device_parent":null}, - "i2c": - { - "CONTROLLERS": - [ - { "dev_name":"i2c-0", "dev":"SMBUS0" } - ] - } - }, - "SMBUS0": - { - "dev_info": {"device_type": "SMBUS", "device_name": "SMBUS0", "device_parent": "SYSTEM"}, - "i2c": - { - "topo_info": {"dev_addr": "0x0"}, - "DEVICES": - [ - {"dev": "EEPROM1"}, - {"dev": "MUX1"} - ] - } - }, - "EEPROM1": - { - "dev_info": {"device_type": "EEPROM", "device_name": "EEPROM1", "device_parent": "SMBUS0"}, - "i2c": - { - "topo_info": {"parent_bus": "0x0", "dev_addr": "0x52", "dev_type": "24lc64t"}, - "dev_attr": {"access_mode": "BLOCK"}, - "attr_list": - [ - {"attr_name": "eeprom"} - ] - } - }, - "MUX1": - { - "dev_info": { "device_type":"MUX", "device_name":"MUX1", "device_parent":"SMBUS0"}, - "i2c": - { - "topo_info": { "parent_bus":"0x0", "dev_addr":"0x70", "dev_type":"pca9548"}, - "dev_attr": { "virt_bus":"0x2"}, - "channel": - [ - {"chn":"0", "dev":"CPLD1" }, - {"chn":"0", "dev":"FAN-CTRL1" }, - {"chn":"2", "dev":"PSU1" }, - {"chn":"2", "dev":"PSU2" }, - {"chn":"3", "dev":"TEMP1"}, - {"chn":"3", "dev":"TEMP2"}, - {"chn":"4", "dev":"TEMP3"}, - {"chn":"4", "dev":"TEMP4"}, - {"chn":"7", "dev":"MUX2"} - ] - } - }, - "MUX2": - { - "dev_info": { "device_type":"MUX", "device_name":"MUX2", "device_parent":"MUX1"}, - "i2c": - { - "topo_info": { "parent_bus":"0x9", "dev_addr":"0x71", "dev_type":"pca9548"}, - "dev_attr": { "virt_bus":"0x10"}, - "channel": - [ - {"chn":"0", "dev":"PORT49"}, - {"chn":"1", "dev":"PORT50"}, - {"chn":"2", "dev":"PORT51"}, - {"chn":"3", "dev":"PORT52"}, - {"chn":"4", "dev":"PORT53"}, - {"chn":"5", "dev":"PORT54"}, - {"chn":"6", "dev":"PORT55"}, - {"chn":"7", "dev":"PORT56"} - ] - } - }, - "CPLD1": - { - "dev_info": {"device_type": "CPLD", "device_name": "CPLD1", "device_parent": "MUX1"}, - "i2c": - { - "topo_info": {"parent_bus": "0x2", "dev_addr": "0x32", "dev_type": "i2c_cpld"}, - "dev_attr": {} - } - }, - "PSU1": - { - "dev_info": { "device_type":"PSU", "device_name":"PSU1", "device_parent":"MUX1"}, - "dev_attr": { "dev_idx":"1", "num_psu_fans": "1"}, - "i2c": - { - "interface": - [ - { "itf":"pmbus", "dev":"PSU1-PMBUS" } - ] - } - }, - "PSU1-PMBUS": - { - "dev_info": { "device_type":"PSU-PMBUS", "device_name":"PSU1-PMBUS", "device_parent":"MUX1", "virt_parent":"PSU1"}, - "i2c": - { - "topo_info":{ "parent_bus":"0x4", "dev_addr":"0x58", "dev_type":"psu_pmbus"}, - "attr_list": - [ - { "attr_name":"psu_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x41", "attr_mask":"0x10", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"psu_power_good", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x41", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"psu_model_name", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"16" }, - { "attr_name":"psu_mfr_id", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x99", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"7" }, - { "attr_name":"psu_serial_num", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x9e", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"16" }, - { "attr_name":"psu_v_in", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x88", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_i_in", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x89", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_p_in", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0xa7", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_v_out", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x8b", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_i_out", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x8c", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_p_out", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x96", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_fan_dir", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0xc5", "attr_mask":"0x18", "attr_cmpval":"0x08", "attr_len":"1"}, - { "attr_name":"psu_fan1_speed_rpm", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x90", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_temp1_input", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x8d", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"} - ] - } - }, - "PSU2": - { - "dev_info": { "device_type":"PSU", "device_name":"PSU2", "device_parent":"MUX1" }, - "dev_attr": { "dev_idx":"2", "num_psu_fans":"1"}, - "i2c": - { - "interface": - [ - { "itf":"pmbus", "dev":"PSU2-PMBUS"} - ] - } - }, - "PSU2-PMBUS": - { - "dev_info": {"device_type":"PSU-PMBUS", "device_name":"PSU2-PMBUS", "device_parent":"MUX1", "virt_parent":"PSU2"}, - "i2c": - { - "topo_info": { "parent_bus":"0x4", "dev_addr":"0x59", "dev_type":"psu_pmbus"}, - "attr_list": - [ - { "attr_name":"psu_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x41", "attr_mask":"0x20", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"psu_power_good", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x41", "attr_mask":"0x8", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"psu_model_name", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"16" }, - { "attr_name":"psu_mfr_id", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x99", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"7" }, - { "attr_name":"psu_serial_num", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x9e", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"16" }, - { "attr_name":"psu_v_in", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x88", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_i_in", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x89", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_p_in", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0xa7", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_v_out", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x8b", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_i_out", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x8c", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_p_out", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x96", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_fan_dir", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0xc5", "attr_mask":"0x18", "attr_cmpval":"0x08", "attr_len":"1"}, - { "attr_name":"psu_fan1_speed_rpm", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x90", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"}, - { "attr_name":"psu_temp1_input", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x8d", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"2"} - ] - } - }, - "TEMP1": - { - "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP1", "device_parent":"MUX1"}, - "dev_attr": { "display_name":"LM75_U10"}, - "i2c": - { - "topo_info": { "parent_bus":"0x5", "dev_addr":"0x48", "dev_type":"lm75"}, - "attr_list": - [ - { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, - { "attr_name": "temp1_max_hyst"}, - { "attr_name": "temp1_input"} - ] - } - }, - "TEMP2": - { - "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP2", "device_parent":"MUX1"}, - "dev_attr": { "display_name":"LM75_U4"}, - "i2c": - { - "topo_info": { "parent_bus":"0x5", "dev_addr":"0x49", "dev_type":"lm75"}, - "attr_list": - [ - { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, - { "attr_name": "temp1_max_hyst"}, - { "attr_name": "temp1_input"} - ] - } - }, - "TEMP3": - { - "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP3", "device_parent":"MUX1"}, - "dev_attr": { "display_name":"LM75_U7"}, - "i2c": - { - "topo_info": { "parent_bus":"0x6", "dev_addr":"0x4a", "dev_type":"lm75"}, - "attr_list": - [ - { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, - { "attr_name": "temp1_max_hyst"}, - { "attr_name": "temp1_input"} - ] - } - }, - "TEMP4": - { - "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP4", "device_parent":"MUX1"}, - "dev_attr": { "display_name":"LM75_U60"}, - "i2c": - { - "topo_info": { "parent_bus":"0x6", "dev_addr":"0x49", "dev_type":"lm75"}, - "attr_list": - [ - { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, - { "attr_name": "temp1_max_hyst"}, - { "attr_name": "temp1_input"} - ] - } - }, - "PORT49": - { - "dev_info": { "device_type":"SFP28", "device_name":"PORT49", "device_parent":"MUX2"}, - "dev_attr": { "dev_idx":"49"}, - "i2c": - { - "interface": - [ - { "itf":"eeprom", "dev":"PORT49-EEPROM" }, - { "itf":"control", "dev":"PORT49-CTRL" } - ] - } - }, - "PORT49-EEPROM": - { - "dev_info": { "device_type":"", "device_name":"PORT49-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT49"}, - "i2c": - { - "topo_info": { "parent_bus":"0x10", "dev_addr":"0x50", "dev_type":"optoe2"}, - "attr_list": - [ - { "attr_name":"eeprom"} - ] - } - }, - "PORT49-CTRL": - { - "dev_info": { "device_type":"", "device_name":"PORT49-CTRL", "device_parent":"MUX2", "virt_parent":"PORT49"}, - "i2c": - { - "topo_info": { "parent_bus":"0x10", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, - "attr_list": - [ - { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"}, - { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"}, - { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"}, - { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"}, - { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x0", "attr_cmpval":"0x1", "attr_len":"1"} - ] - } - }, - "PORT50": - { - "dev_info": { "device_type":"SFP28", "device_name":"PORT50", "device_parent":"MUX2"}, - "dev_attr": { "dev_idx":"50"}, - "i2c": - { - "interface": - [ - { "itf":"eeprom", "dev":"PORT50-EEPROM" }, - { "itf":"control", "dev":"PORT50-CTRL" } - ] - } - }, - "PORT50-EEPROM": - { - "dev_info": { "device_type":"", "device_name":"PORT50-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT50"}, - "i2c": - { - "topo_info": { "parent_bus":"0x11", "dev_addr":"0x50", "dev_type":"optoe2"}, - "attr_list": - [ - { "attr_name":"eeprom"} - ] - } - }, - "PORT50-CTRL": - { - "dev_info": { "device_type":"", "device_name":"PORT50-CTRL", "device_parent":"MUX2", "virt_parent":"PORT50"}, - "i2c": - { - "topo_info": { "parent_bus":"0x11", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, - "attr_list": - [ - { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"}, - { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"}, - { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"}, - { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"}, - { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"} - - ] - } - }, - "PORT51": - { - "dev_info": { "device_type":"SFP28", "device_name":"PORT51", "device_parent":"MUX2"}, - "dev_attr": { "dev_idx":"51"}, - "i2c": - { - "interface": - [ - { "itf":"eeprom", "dev":"PORT51-EEPROM" }, - { "itf":"control", "dev":"PORT51-CTRL" } - ] - } - }, - "PORT51-EEPROM": - { - "dev_info": { "device_type":"", "device_name":"PORT51-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT51"}, - "i2c": - { - "topo_info": { "parent_bus":"0x12", "dev_addr":"0x50", "dev_type":"optoe2"}, - "attr_list": - [ - { "attr_name":"eeprom"} - ] - } - }, - "PORT51-CTRL": - { - "dev_info": { "device_type":"", "device_name":"PORT51-CTRL", "device_parent":"MUX2", "virt_parent":"PORT51"}, - "i2c": - { - "topo_info": { "parent_bus":"0x12", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, - "attr_list": - [ - { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x2", "attr_cmpval":"0x4", "attr_len":"1"}, - { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x2", "attr_cmpval":"0x4", "attr_len":"1"}, - { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x2", "attr_cmpval":"0x4", "attr_len":"1"}, - { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x2", "attr_cmpval":"0x4", "attr_len":"1"}, - { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x2", "attr_cmpval":"0x4", "attr_len":"1"} - ] - } - }, - "PORT52": - { - "dev_info": { "device_type":"SFP28", "device_name":"PORT52", "device_parent":"MUX2"}, - "dev_attr": { "dev_idx":"52"}, - "i2c": - { - "interface": - [ - { "itf":"eeprom", "dev":"PORT52-EEPROM" }, - { "itf":"control", "dev":"PORT52-CTRL" } - ] - } - }, - "PORT52-EEPROM": - { - "dev_info": { "device_type":"", "device_name":"PORT52-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT52"}, - "i2c": - { - "topo_info": { "parent_bus":"0x13", "dev_addr":"0x50", "dev_type":"optoe2"}, - "attr_list": - [ - { "attr_name":"eeprom"} - ] - } - }, - "PORT52-CTRL": - { - "dev_info": { "device_type":"", "device_name":"PORT52-CTRL", "device_parent":"MUX2", "virt_parent":"PORT52"}, - "i2c": - { - "topo_info": { "parent_bus":"0x13", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, - "attr_list": - [ - { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x3", "attr_cmpval":"0x8", "attr_len":"1"}, - { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x3", "attr_cmpval":"0x8", "attr_len":"1"}, - { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x3", "attr_cmpval":"0x8", "attr_len":"1"}, - { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x3", "attr_cmpval":"0x8", "attr_len":"1"}, - { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x3", "attr_cmpval":"0x8", "attr_len":"1"} - - ] - } - }, - "PORT53": - { - "dev_info": { "device_type":"SFP28", "device_name":"PORT53", "device_parent":"MUX2"}, - "dev_attr": { "dev_idx":"53"}, - "i2c": - { - "interface": - [ - { "itf":"eeprom", "dev":"PORT53-EEPROM" }, - { "itf":"control", "dev":"PORT53-CTRL" } - ] - } - }, - "PORT53-EEPROM": - { - "dev_info": { "device_type":"", "device_name":"PORT53-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT53"}, - "i2c": - { - "topo_info": { "parent_bus":"0x14", "dev_addr":"0x50", "dev_type":"optoe2"}, - "attr_list": - [ - { "attr_name":"eeprom"} - ] - } - }, - "PORT53-CTRL": - { - "dev_info": { "device_type":"", "device_name":"PORT53-CTRL", "device_parent":"MUX2", "virt_parent":"PORT53"}, - "i2c": - { - "topo_info": { "parent_bus":"0x14", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, - "attr_list": - [ - { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"}, - { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"}, - { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"}, - { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"}, - { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} - - ] - } - }, - "PORT54": - { - "dev_info": { "device_type":"SFP28", "device_name":"PORT54", "device_parent":"MUX2"}, - "dev_attr": { "dev_idx":"54"}, - "i2c": - { - "interface": - [ - { "itf":"eeprom", "dev":"PORT54-EEPROM" }, - { "itf":"control", "dev":"PORT54-CTRL" } - ] - } - }, - "PORT54-EEPROM": - { - "dev_info": { "device_type":"", "device_name":"PORT54-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT54"}, - "i2c": - { - "topo_info": { "parent_bus":"0x15", "dev_addr":"0x50", "dev_type":"optoe2"}, - "attr_list": - [ - { "attr_name":"eeprom"} - ] - } - }, - "PORT54-CTRL": - { - "dev_info": { "device_type":"", "device_name":"PORT54-CTRL", "device_parent":"MUX2", "virt_parent":"PORT54"}, - "i2c": - { - "topo_info": { "parent_bus":"0x15", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, - "attr_list": - [ - { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x5", "attr_cmpval":"0x20", "attr_len":"1"}, - { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x5", "attr_cmpval":"0x20", "attr_len":"1"}, - { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x5", "attr_cmpval":"0x20", "attr_len":"1"}, - { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x5", "attr_cmpval":"0x20", "attr_len":"1"}, - { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x5", "attr_cmpval":"0x20", "attr_len":"1"} - ] - } - }, - "PORT55": - { - "dev_info": { "device_type":"SFP28", "device_name":"PORT55", "device_parent":"MUX2"}, - "dev_attr": { "dev_idx":"55"}, - "i2c": - { - "interface": - [ - { "itf":"eeprom", "dev":"PORT55-EEPROM" }, - { "itf":"control", "dev":"PORT55-CTRL" } - ] - } - }, - "PORT55-EEPROM": - { - "dev_info": { "device_type":"", "device_name":"PORT55-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT55"}, - "i2c": - { - "topo_info": { "parent_bus":"0x16", "dev_addr":"0x50", "dev_type":"optoe2"}, - "attr_list": - [ - { "attr_name":"eeprom"} - ] - } - }, - "PORT55-CTRL": - { - "dev_info": { "device_type":"", "device_name":"PORT55-CTRL", "device_parent":"MUX2", "virt_parent":"PORT55"}, - "i2c": - { - "topo_info": { "parent_bus":"0x16", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, - "attr_list": - [ - { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, - { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, - { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, - { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, - { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"} - ] - } - }, - "PORT56": - { - "dev_info": { "device_type":"SFP28", "device_name":"PORT56", "device_parent":"MUX2"}, - "dev_attr": { "dev_idx":"56"}, - "i2c": - { - "interface": - [ - { "itf":"eeprom", "dev":"PORT56-EEPROM" }, - { "itf":"control", "dev":"PORT56-CTRL" } - ] - } - }, - "PORT56-EEPROM": - { - "dev_info": { "device_type":"", "device_name":"PORT56-EEPROM", "device_parent":"MUX2", "virt_parent":"PORT56"}, - "i2c": - { - "topo_info": { "parent_bus":"0x17", "dev_addr":"0x50", "dev_type":"optoe2"}, - "attr_list": - [ - { "attr_name":"eeprom"} - ] - } - }, - "PORT56-CTRL": - { - "dev_info": { "device_type":"", "device_name":"PORT56-CTRL", "device_parent":"MUX2", "virt_parent":"PORT56"}, - "i2c": - { - "topo_info": { "parent_bus":"0x17", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, - "attr_list": - [ - { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x7", "attr_cmpval":"0x80", "attr_len":"1"}, - { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x7", "attr_cmpval":"0x80", "attr_len":"1"}, - { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x7", "attr_cmpval":"0x80", "attr_len":"1"}, - { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x7", "attr_cmpval":"0x80", "attr_len":"1"}, - { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x7", "attr_cmpval":"0x80", "attr_len":"1"} - ] - } - }, - "FAN-CTRL1": - { - "dev_info": { "device_type":"FAN", "device_name":"FAN-CTRL1", "device_parent":"MUX1"}, - "i2c": - { - "topo_info": { "parent_bus":"0x2", "dev_addr":"0x66", "dev_type":"fan_cpld"}, - "dev_attr": { "num_fantrays":"3"}, - "attr_list": - [ - { "attr_name":"fan1_pwm", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x32", "attr_mask":"0xff", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan2_pwm", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x36", "attr_mask":"0xff", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan3_pwm", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x3a", "attr_mask":"0xff", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan1_direction", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x88", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan2_direction", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x88", "attr_mask":"0x2", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan3_direction", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x88", "attr_mask":"0x1", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan1_input", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x31", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"150", "attr_is_divisor":0}, - { "attr_name":"fan2_input", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x35", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"150" , "attr_is_divisor":0}, - { "attr_name":"fan3_input", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x39", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"150", "attr_is_divisor":0} - ] - } - }, - "SYS_LED": - { - "dev_info": { "device_type":"LED", "device_name":"SYS_LED"}, - "dev_attr": { "index":"0", "flag": "rw"}, - "i2c" : { - "attr_list": - [ - {"attr_name":"amber","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x1","swpld_addr_offset":"0x43"}, - {"attr_name":"green","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x2","swpld_addr_offset":"0x43"}, - {"attr_name":"off","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x0","swpld_addr_offset":"0x43"} - ] - } - }, - "FANTRAY1_LED": - { - "dev_info": { "device_type":"LED", "device_name":"FANTRAY_LED"}, - "dev_attr": { "index":"0", "flag": "rw"}, - "i2c" : { - "attr_list": - [ - {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x33"}, - {"attr_name":"red","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x33"} - ] - } - }, - "FANTRAY2_LED": - { - "dev_info": { "device_type":"LED", "device_name":"FANTRAY_LED"}, - "dev_attr": { "index":"1", "flag": "rw"}, - "i2c" : { - "attr_list": - [ - {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x37"}, - {"attr_name":"red","attr_devtype":"cpld","attr_devname":"CPLD1B","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x37"} - ] - } - }, - "FANTRAY3_LED": - { - "dev_info": { "device_type":"LED", "device_name":"FANTRAY_LED"}, - "dev_attr": { "index":"2", "flag": "rw"}, - "i2c" : { - "attr_list": - [ - {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x3b"}, - {"attr_name":"red","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x3b"} - ] - } - } -} diff --git a/device/celestica/x86_64-cel_belgite-r0/platform_components.json b/device/celestica/x86_64-cel_belgite-r0/platform_components.json deleted file mode 100644 index 23a4ce41cd..0000000000 --- a/device/celestica/x86_64-cel_belgite-r0/platform_components.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "chassis": { - "E1070": { - "component": { - "SWCPLD": {}, - "BIOS": {} - } - } - } -} diff --git a/device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/belgite.config.bcm b/device/celestica/x86_64-cel_ds1000-r0/DS1000/ds1000.config.bcm similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/belgite.config.bcm rename to device/celestica/x86_64-cel_ds1000-r0/DS1000/ds1000.config.bcm diff --git a/device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/hwsku.json b/device/celestica/x86_64-cel_ds1000-r0/DS1000/hwsku.json similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/CELESTICA-BELGITE/hwsku.json rename to device/celestica/x86_64-cel_ds1000-r0/DS1000/hwsku.json diff --git a/device/celestica/x86_64-cel_ds1000-r0/DS1000/port_config.ini b/device/celestica/x86_64-cel_ds1000-r0/DS1000/port_config.ini new file mode 100644 index 0000000000..123c4f10df --- /dev/null +++ b/device/celestica/x86_64-cel_ds1000-r0/DS1000/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed autoneg +Ethernet0 26 Eth1/1 1 1000 1 +Ethernet1 25 Eth2/1 2 1000 1 +Ethernet2 28 Eth3/1 3 1000 1 +Ethernet3 27 Eth4/1 4 1000 1 +Ethernet4 30 Eth5/1 5 1000 1 +Ethernet5 29 Eth6/1 6 1000 1 +Ethernet6 32 Eth7/1 7 1000 1 +Ethernet7 31 Eth8/1 8 1000 1 +Ethernet8 34 Eth9/1 9 1000 1 +Ethernet9 33 Eth10/1 10 1000 1 +Ethernet10 36 Eth11/1 11 1000 1 +Ethernet11 35 Eth12/1 12 1000 1 +Ethernet12 38 Eth13/1 13 1000 1 +Ethernet13 37 Eth14/1 14 1000 1 +Ethernet14 40 Eth15/1 15 1000 1 +Ethernet15 39 Eth16/1 16 1000 1 +Ethernet16 42 Eth17/1 17 1000 1 +Ethernet17 41 Eth18/1 18 1000 1 +Ethernet18 44 Eth19/1 19 1000 1 +Ethernet19 43 Eth20/1 20 1000 1 +Ethernet20 50 Eth21/1 21 1000 1 +Ethernet21 49 Eth22/1 22 1000 1 +Ethernet22 52 Eth23/1 23 1000 1 +Ethernet23 51 Eth24/1 24 1000 1 +Ethernet24 2 Eth25/1 25 1000 1 +Ethernet25 1 Eth26/1 26 1000 1 +Ethernet26 4 Eth27/1 27 1000 1 +Ethernet27 3 Eth28/1 28 1000 1 +Ethernet28 6 Eth29/1 29 1000 1 +Ethernet29 5 Eth30/1 30 1000 1 +Ethernet30 8 Eth31/1 31 1000 1 +Ethernet31 7 Eth32/1 32 1000 1 +Ethernet32 10 Eth33/1 33 1000 1 +Ethernet33 9 Eth34/1 34 1000 1 +Ethernet34 12 Eth35/1 35 1000 1 +Ethernet35 11 Eth36/1 36 1000 1 +Ethernet36 14 Eth37/1 37 1000 1 +Ethernet37 13 Eth38/1 38 1000 1 +Ethernet38 16 Eth39/1 39 1000 1 +Ethernet39 15 Eth40/1 40 1000 1 +Ethernet40 18 Eth41/1 41 1000 1 +Ethernet41 17 Eth42/1 42 1000 1 +Ethernet42 20 Eth43/1 43 1000 1 +Ethernet43 19 Eth44/1 44 1000 1 +Ethernet44 22 Eth45/1 45 1000 1 +Ethernet45 21 Eth46/1 46 1000 1 +Ethernet46 24 Eth47/1 47 1000 1 +Ethernet47 23 Eth48/1 48 1000 1 +Ethernet48 60 Eth49/1 49 10000 0 +Ethernet49 58 Eth50/1 50 10000 0 +Ethernet50 59 Eth51/1 51 10000 0 +Ethernet51 57 Eth52/1 52 10000 0 +Ethernet52 62 Eth53/1 53 10000 0 +Ethernet53 64 Eth54/1 54 10000 0 +Ethernet54 61 Eth55/1 55 10000 0 +Ethernet55 63 Eth56/1 56 10000 0 diff --git a/device/celestica/x86_64-cel_ds1000-r0/DS1000/sai.profile b/device/celestica/x86_64-cel_ds1000-r0/DS1000/sai.profile new file mode 100644 index 0000000000..d58abd359c --- /dev/null +++ b/device/celestica/x86_64-cel_ds1000-r0/DS1000/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/ds1000.config.bcm diff --git a/device/celestica/x86_64-cel_ds1000-r0/custom_led.bin b/device/celestica/x86_64-cel_ds1000-r0/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..1fe3d5abac5a44b16f6ae059e0811f236295265f GIT binary patch literal 272 zcmWN}J1;|V7{KA*zpdMG+^eW-PjBj2w3VVR)i$qz1zTgFBI)QO2nHi!kTUoPa*_^` zN@}vn!6cS0Qjtg+qlxDOJoVC(tjIwruoh-NLC_ge#)UYIGjSMN>QwaVVc}(KSG=iJ zDSFSXOd+@Fh`XlCY2EgpsN|JZL=`r2p7fU;Wm$-PKY!FP@ag_*InJtZBBUiRMO7cR zRrJ-u{I!*-*>1Hbk#!Y&w_N7WTcvy_w^F}<+);VSXXGgVS*ys+3=H69kRgT{VU#g^ z|Fxe0K|+KXC&C0KlS~mMMjV9$CoURjq={x)&}c=cpFTYF;--ggy6B{XcG{R{jwG`z Jl45}+{s5hIKs^8e literal 0 HcmV?d00001 diff --git a/device/celestica/x86_64-cel_ds1000-r0/default_sku b/device/celestica/x86_64-cel_ds1000-r0/default_sku new file mode 100644 index 0000000000..e83707dd8d --- /dev/null +++ b/device/celestica/x86_64-cel_ds1000-r0/default_sku @@ -0,0 +1 @@ +DS1000 t1 diff --git a/device/celestica/x86_64-cel_belgite-r0/installer.conf b/device/celestica/x86_64-cel_ds1000-r0/installer.conf similarity index 83% rename from device/celestica/x86_64-cel_belgite-r0/installer.conf rename to device/celestica/x86_64-cel_ds1000-r0/installer.conf index 4304739333..fbc96da177 100644 --- a/device/celestica/x86_64-cel_belgite-r0/installer.conf +++ b/device/celestica/x86_64-cel_ds1000-r0/installer.conf @@ -1,4 +1,4 @@ -CONSOLE_PORT=0x3f8 +CONSOLE_PORT=0xe060 CONSOLE_DEV=0 -CONSOLE_SPEED=9600 +CONSOLE_SPEED=115200 ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_iommu=off modprobe.blacklist=gpio_ich,i2c-ismt,i2c_ismt,i2c-i801,i2c_i801 crashkernel=0M-2G:256M,2G-4G:320M,4G-8G:384M,8G-:448M acpi_no_watchdog" diff --git a/device/celestica/x86_64-cel_belgite-r0/led-source-code/cmicx/Makefile b/device/celestica/x86_64-cel_ds1000-r0/led-source-code/cmicx/Makefile similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/led-source-code/cmicx/Makefile rename to device/celestica/x86_64-cel_ds1000-r0/led-source-code/cmicx/Makefile diff --git a/device/celestica/x86_64-cel_belgite-r0/led-source-code/cmicx/custom_led.c b/device/celestica/x86_64-cel_ds1000-r0/led-source-code/cmicx/custom_led.c similarity index 81% rename from device/celestica/x86_64-cel_belgite-r0/led-source-code/cmicx/custom_led.c rename to device/celestica/x86_64-cel_ds1000-r0/led-source-code/cmicx/custom_led.c index 712b5503e3..09d73c109a 100755 --- a/device/celestica/x86_64-cel_belgite-r0/led-source-code/cmicx/custom_led.c +++ b/device/celestica/x86_64-cel_ds1000-r0/led-source-code/cmicx/custom_led.c @@ -89,14 +89,25 @@ Here is an exception, please keep in mind: #include #define ACTIVITY_TICKS 2 -#define READ_LED_ACCU_DATA(base, port) (*((uint16 *)(base + ((port - 1) * sizeof(uint32))))) -#define WRITE_LED_SEND_DATA(base, port, val) (*((uint16 *)(base + ((port - 1) * sizeof(uint32)))) = val) + +/*! Macro to calculate LED RAM address. */ +#define LED_HW_RAM_ADDR(base, port) \ + (base + (port * sizeof(uint32))) + +/*! Macro to read LED RAM. */ +#define LED_HW_RAM_READ16(base, port) \ + *((uint16 *) LED_HW_RAM_ADDR(base, port)) + +/*! Macro to write LED RAM. */ +#define LED_HW_RAM_WRITE16(base, port, val) \ + *((uint16 *) LED_HW_RAM_ADDR(base, port)) = (val) #define PORT_NUM_TOTAL 56 #define LED_GREEN_BICOLOR 0x2 //bit : 10 #define LED_AMBER_BICOLOR 0x1 //bit : 01 #define LED_OFF_BICOLOR 0x3 //bit : 11 +#define LED_SW_LINK_UP 0x1 unsigned short portmap[] = { 25, 26, 27, 28, 29, 30, 31, 32, @@ -123,47 +134,58 @@ unsigned short portmap[] = { void custom_led_handler(soc_led_custom_handler_ctrl_t *ctrl, uint32 activity_count) { - unsigned short accu_val = 0, send_val = 0; - unsigned short port, physical_port; + uint8 idx = 0; + uint16 accu_val = 0, send_val = 0; + uint16 uc_port = 0, physical_port = 0; /* Physical port numbers to be used */ - for(port = 1; port <= PORT_NUM_TOTAL; port++) { + for(uc_port = 0; uc_port < PORT_NUM_TOTAL; uc_port++) { - physical_port = portmap[port-1]; + // change to zero-based + physical_port = portmap[uc_port] - 1; /* Read value from led_ram bank0 */ - accu_val = READ_LED_ACCU_DATA(ctrl->accu_ram_base, physical_port); + accu_val = LED_HW_RAM_READ16(ctrl->accu_ram_base, physical_port); - send_val = 0xff; + send_val = LED_OFF_BICOLOR; - if (((accu_val & LED_OUTPUT_RX) || (accu_val & LED_OUTPUT_TX)) && (activity_count & ACTIVITY_TICKS)) + if (((accu_val & LED_HW_RX) || (accu_val & LED_HW_TX)) && (activity_count & ACTIVITY_TICKS)) { send_val = LED_OFF_BICOLOR; } - else if ( accu_val & LED_OUTPUT_LINK_UP) + else if (ctrl->led_control_data[physical_port] & LED_SW_LINK_UP) { send_val = LED_GREEN_BICOLOR; } else { send_val = LED_OFF_BICOLOR; - } + } /* Write value to led_ram bank1 */ - WRITE_LED_SEND_DATA(ctrl->pat_ram_base, port, send_val); + LED_HW_RAM_WRITE16(ctrl->pat_ram_base, uc_port, send_val); } /* for */ - /* Send the pattern over LED interface 1 for ports 1 - 56*/ - ctrl->intf_ctrl[1].valid = 1; - ctrl->intf_ctrl[1].start_row = 0; - ctrl->intf_ctrl[1].end_row = 55; - ctrl->intf_ctrl[1].pat_width = 2; + /* Configure LED HW interfaces based on board configuration */ + for (idx = 0; idx < LED_HW_INTF_MAX_NUM; idx++) { + soc_led_intf_ctrl_t *lic = &ctrl->intf_ctrl[idx]; + switch (idx) { + case 0: + lic->valid = 0; + break; + case 1: + lic->valid = 1; + lic->start_row = 0; + lic->end_row = 55; + lic->pat_width = 2; + break; + default: - /* Invalidate rest of the interfaces */ - ctrl->intf_ctrl[0].valid = 0; - ctrl->intf_ctrl[2].valid = 0; - ctrl->intf_ctrl[3].valid = 0; - ctrl->intf_ctrl[4].valid = 0; + /* Invalidate rest of the interfaces */ + lic->valid = 0; + break; + } + } return; diff --git a/device/celestica/x86_64-cel_belgite-r0/led-source-code/cmicx/custom_led.lds b/device/celestica/x86_64-cel_ds1000-r0/led-source-code/cmicx/custom_led.lds similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/led-source-code/cmicx/custom_led.lds rename to device/celestica/x86_64-cel_ds1000-r0/led-source-code/cmicx/custom_led.lds diff --git a/device/celestica/x86_64-cel_belgite-r0/led_proc_init.soc b/device/celestica/x86_64-cel_ds1000-r0/led_proc_init.soc similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/led_proc_init.soc rename to device/celestica/x86_64-cel_ds1000-r0/led_proc_init.soc diff --git a/device/celestica/x86_64-cel_belgite-r0/media_settings.json b/device/celestica/x86_64-cel_ds1000-r0/media_settings.json similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/media_settings.json rename to device/celestica/x86_64-cel_ds1000-r0/media_settings.json diff --git a/device/celestica/x86_64-cel_belgite-r0/pcie.yaml b/device/celestica/x86_64-cel_ds1000-r0/pcie.yaml similarity index 56% rename from device/celestica/x86_64-cel_belgite-r0/pcie.yaml rename to device/celestica/x86_64-cel_ds1000-r0/pcie.yaml index 46e2025267..47e5ecbead 100644 --- a/device/celestica/x86_64-cel_belgite-r0/pcie.yaml +++ b/device/celestica/x86_64-cel_ds1000-r0/pcie.yaml @@ -1,121 +1,143 @@ - bus: '00' dev: '00' fn: '0' - id: 1980 - name: 'Host bridge: Intel Corporation Atom Processor C3000 Series System Agent' + id: '1980' + name: 'Host bridge: Intel Corporation Atom Processor C3000 Series System Agent (rev + 11)' - bus: '00' dev: '04' fn: '0' id: 19a1 - name: 'Host bridge: Intel Corporation Atom Processor C3000 Series Error Registers' + name: 'Host bridge: Intel Corporation Atom Processor C3000 Series Error Registers + (rev 11)' - bus: '00' dev: '05' fn: '0' id: 19a2 - name: 'Generic system peripheral [0807]: Intel Corporation Atom Processor C3000 Series Root Complex Event Collector' + name: 'Generic system peripheral [0807]: Intel Corporation Atom Processor C3000 + Series Root Complex Event Collector (rev 11)' - bus: '00' dev: '06' fn: '0' - id: 19e2 - name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated QAT Root Port' + id: 19a3 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated QAT + Root Port (rev 11)' - bus: '00' - dev: '09' + dev: 09 fn: '0' - id: b277 - name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root Port' + id: 19a4 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #0 (rev 11)' - bus: '00' - dev: '0b' + dev: 0b fn: '0' - id: 1533 - name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root Port' + id: 19a6 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #2 (rev 11)' - bus: '00' - dev: '0e' + dev: 0e fn: '0' id: 19a8 - name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root Port' + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #4 (rev 11)' - bus: '00' dev: '12' fn: '0' id: 19ac - name: 'System peripheral: Intel Corporation DNV SMBus Contoller - Host' + name: 'System peripheral: Intel Corporation Atom Processor C3000 Series SMBus Contoller + - Host (rev 11)' - bus: '00' dev: '14' fn: '0' id: 19c2 - name: 'SATA controller: Intel Corporation DNV SATA Controller 1' + name: 'SATA controller: Intel Corporation Atom Processor C3000 Series SATA Controller + 1 (rev 11)' - bus: '00' dev: '15' fn: '0' id: 19d0 - name: 'USB controller: Intel Corporation Atom Processor C3000 Series USB 3.0 xHCI Controller' + name: 'USB controller: Intel Corporation Atom Processor C3000 Series USB 3.0 xHCI + Controller (rev 11)' - bus: '00' dev: '16' fn: '0' - id: 15ce - name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated LAN Root Port' + id: 19d1 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated LAN + Root Port #0 (rev 11)' - bus: '00' dev: '18' fn: '0' id: 19d3 - name: 'Communication controller: Intel Corporation Atom Processor C3000 Series ME HECI 1' + name: 'Communication controller: Intel Corporation Atom Processor C3000 Series ME + HECI 1 (rev 11)' - bus: '00' - dev: '1a' + dev: 1a fn: '0' id: 19d8 - name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller' + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' - bus: '00' - dev: '1a' + dev: 1a fn: '1' id: 19d8 - name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller' + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' - bus: '00' - dev: '1a' + dev: 1a fn: '2' id: 19d8 - name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller' + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' - bus: '00' - dev: '1f' + dev: 1f fn: '0' id: 19dc - name: 'ISA bridge: Intel Corporation DNV LPC or eSPI' + name: 'ISA bridge: Intel Corporation Atom Processor C3000 Series LPC or eSPI (rev + 11)' - bus: '00' - dev: '1f' + dev: 1f fn: '2' id: 19de - name: 'Memory controller: Intel Corporation Atom Processor C3000 Series Power Management Controller' + name: 'Memory controller: Intel Corporation Atom Processor C3000 Series Power Management + Controller (rev 11)' - bus: '00' - dev: '1f' + dev: 1f fn: '4' id: 19df - name: 'SMBus: Intel Corporation DNV SMBus controller' + name: 'SMBus: Intel Corporation Atom Processor C3000 Series SMBus controller (rev + 11)' - bus: '00' - dev: '1f' + dev: 1f fn: '5' id: 19e0 - name: 'Serial bus controller [0c80]: Intel Corporation DNV SPI Controller' + name: 'Serial bus controller [0c80]: Intel Corporation Atom Processor C3000 Series + SPI Controller (rev 11)' - bus: '01' dev: '00' fn: '0' id: 19e2 - name: 'Co-processor: Intel Corporation Atom Processor C3000 Series QuickAssist Technology' + name: 'Co-processor: Intel Corporation Atom Processor C3000 Series QuickAssist Technology + (rev 11)' - bus: '02' dev: '00' fn: '0' id: b277 - name: 'Ethernet controller: Broadcom Limited Device b277' + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b277 (rev 02)' - bus: '03' dev: '00' fn: '0' - id: 1533 - name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' - bus: '05' dev: '00' fn: '0' - id: 15ce - name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 10 GbE SFP+' + id: 15c2 + name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane + (rev 11)' - bus: '05' dev: '00' fn: '1' - id: 15ce - name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 10 GbE SFP+' - + id: 15c2 + name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane + (rev 11)' diff --git a/device/celestica/x86_64-cel_belgite-r0/pddf/pd-plugin.json b/device/celestica/x86_64-cel_ds1000-r0/pddf/pd-plugin.json similarity index 89% rename from device/celestica/x86_64-cel_belgite-r0/pddf/pd-plugin.json rename to device/celestica/x86_64-cel_ds1000-r0/pddf/pd-plugin.json index 454afd2399..04c81d3288 100644 --- a/device/celestica/x86_64-cel_belgite-r0/pddf/pd-plugin.json +++ b/device/celestica/x86_64-cel_ds1000-r0/pddf/pd-plugin.json @@ -29,7 +29,7 @@ { "i2c": { - "valmap": { "0":"INTAKE", "1":"EXHAUST" } + "valmap": { "0":"intake", "1":"exhaust" } } }, "PSU_FAN_MAX_SPEED":"18000" @@ -40,7 +40,7 @@ { "i2c": { - "valmap": {"1":"EXHAUST", "0":"INTAKE"} + "valmap": {"1":"exhaust", "0":"intake"} } }, "present": diff --git a/device/celestica/x86_64-cel_belgite-r0/pddf/pddf-device.json b/device/celestica/x86_64-cel_ds1000-r0/pddf/pddf-device.json similarity index 87% rename from device/celestica/x86_64-cel_belgite-r0/pddf/pddf-device.json rename to device/celestica/x86_64-cel_ds1000-r0/pddf/pddf-device.json index a97102c1f4..7a726ce4de 100644 --- a/device/celestica/x86_64-cel_belgite-r0/pddf/pddf-device.json +++ b/device/celestica/x86_64-cel_ds1000-r0/pddf/pddf-device.json @@ -8,7 +8,7 @@ "num_temps":4, "pddf_dev_types": { - "description":"Belgite - Below is the list of supported PDDF device types (chip names) for various components. If any component uses some other driver, we will create the client using 'echo > /new_device' method", + "description":"DS1000 - Below is the list of supported PDDF device types (chip names) for various components. If any component uses some other driver, we will create the client using 'echo > /new_device' method", "CPLD": [ "i2c_cpld" @@ -39,7 +39,7 @@ "i2c_dev", "i2c_mux_pca954x force_deselect_on_exit=1", "gpio_pca953x", - "mc24lc64t", + "mc24lc64t", "optoe" ], "pddf_kos": @@ -55,8 +55,8 @@ "pddf_fan_driver_module", "pddf_fan_module", "pddf_led_module" - ], - "custom_kos": + ], + "custom_kos": [ "pddf_custom_psu", "pddf_custom_wdt" @@ -93,7 +93,7 @@ { "topo_info": {"parent_bus": "0x0", "dev_addr": "0x52", "dev_type": "24lc64t"}, "dev_attr": {"access_mode": "BLOCK"}, - "attr_list": + "attr_list": [ {"attr_name": "eeprom"} ] @@ -110,13 +110,13 @@ [ {"chn":"0", "dev":"CPLD1" }, {"chn":"0", "dev":"FAN-CTRL" }, - {"chn":"2", "dev":"PSU1" }, + {"chn":"2", "dev":"PSU1" }, {"chn":"2", "dev":"PSU2" }, {"chn":"3", "dev":"TEMP1"}, {"chn":"3", "dev":"TEMP2"}, {"chn":"4", "dev":"TEMP3"}, - {"chn":"4", "dev":"TEMP4"}, - {"chn":"7", "dev":"MUX2"} + {"chn":"4", "dev":"TEMP4"}, + {"chn":"7", "dev":"MUX2"} ] } }, @@ -130,13 +130,13 @@ "channel": [ {"chn":"0", "dev":"PORT49"}, - {"chn":"1", "dev":"PORT50"}, + {"chn":"1", "dev":"PORT50"}, {"chn":"2", "dev":"PORT51"}, {"chn":"3", "dev":"PORT52"}, {"chn":"4", "dev":"PORT53"}, {"chn":"5", "dev":"PORT54"}, {"chn":"6", "dev":"PORT55"}, - {"chn":"7", "dev":"PORT56"} + {"chn":"7", "dev":"PORT56"} ] } }, @@ -151,7 +151,7 @@ }, "PSU1": { - "dev_info": { "device_type":"PSU", "device_name":"PSU1", "device_parent":"MUX1"}, + "dev_info": { "device_type":"PSU", "device_name":"PSU 1", "device_parent":"MUX1"}, "dev_attr": { "dev_idx":"1", "num_psu_fans": "1"}, "i2c": { @@ -168,7 +168,7 @@ { "topo_info":{ "parent_bus":"0x4", "dev_addr":"0x58", "dev_type":"psu_pmbus"}, "attr_list": - [ + [ { "attr_name":"psu_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x41", "attr_mask":"0x10", "attr_cmpval":"0x0", "attr_len":"1"}, { "attr_name":"psu_power_good", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x41", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, { "attr_name":"psu_model_name", "attr_devaddr":"0x58", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"13" }, @@ -187,7 +187,7 @@ }, "PSU2": { - "dev_info": { "device_type":"PSU", "device_name":"PSU2", "device_parent":"MUX1" }, + "dev_info": { "device_type":"PSU", "device_name":"PSU 2", "device_parent":"MUX1" }, "dev_attr": { "dev_idx":"2", "num_psu_fans":"1"}, "i2c": { @@ -204,7 +204,7 @@ { "topo_info": { "parent_bus":"0x4", "dev_addr":"0x59", "dev_type":"psu_pmbus"}, "attr_list": - [ + [ { "attr_name":"psu_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x41", "attr_mask":"0x20", "attr_cmpval":"0x0", "attr_len":"1"}, { "attr_name":"psu_power_good", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x41", "attr_mask":"0x8", "attr_cmpval":"0x0", "attr_len":"1"}, { "attr_name":"psu_model_name", "attr_devaddr":"0x59", "attr_devtype":"pmbus", "attr_offset":"0x9a", "attr_mask":"0x0", "attr_cmpval":"0xff", "attr_len":"13" }, @@ -221,16 +221,16 @@ ] } }, - "TEMP1": + "TEMP1": { "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP1", "device_parent":"MUX1"}, - "dev_attr": { "display_name":"LM75_U10"}, + "dev_attr": { "display_name":"Front Left Temp"}, "i2c": { "topo_info": { "parent_bus":"0x5", "dev_addr":"0x48", "dev_type":"lm75"}, "attr_list": [ - { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max"}, { "attr_name": "temp1_max_hyst"}, { "attr_name": "temp1_input"} ] @@ -239,13 +239,13 @@ "TEMP2": { "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP2", "device_parent":"MUX1"}, - "dev_attr": { "display_name":"LM75_U4"}, + "dev_attr": { "display_name":"Front Right Temp"}, "i2c": { "topo_info": { "parent_bus":"0x5", "dev_addr":"0x49", "dev_type":"lm75"}, "attr_list": [ - { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max"}, { "attr_name": "temp1_max_hyst"}, { "attr_name": "temp1_input"} ] @@ -254,33 +254,33 @@ "TEMP3": { "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP3", "device_parent":"MUX1"}, - "dev_attr": { "display_name":"LM75_U7"}, + "dev_attr": { "display_name":"Rear Right Temp"}, "i2c": { "topo_info": { "parent_bus":"0x6", "dev_addr":"0x4a", "dev_type":"lm75"}, "attr_list": [ - { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max"}, { "attr_name": "temp1_max_hyst"}, { "attr_name": "temp1_input"} ] } - }, + }, "TEMP4": { "dev_info": { "device_type":"TEMP_SENSOR", "device_name":"TEMP4", "device_parent":"MUX1"}, - "dev_attr": { "display_name":"LM75_U60"}, + "dev_attr": { "display_name":"ASIC External Temp"}, "i2c": { "topo_info": { "parent_bus":"0x6", "dev_addr":"0x49", "dev_type":"lm75"}, "attr_list": [ - { "attr_name": "temp1_high_threshold", "drv_attr_name":"temp1_max"}, + { "attr_name": "temp1_max"}, { "attr_name": "temp1_max_hyst"}, { "attr_name": "temp1_input"} ] } - }, + }, "PORT49": { "dev_info": { "device_type":"SFP+", "device_name":"PORT49", "device_parent":"MUX2"}, @@ -360,7 +360,6 @@ { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"}, { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"}, { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x1", "attr_cmpval":"0x2", "attr_len":"1"} - ] } }, @@ -443,7 +442,6 @@ { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x3", "attr_cmpval":"0x8", "attr_len":"1"}, { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x3", "attr_cmpval":"0x8", "attr_len":"1"}, { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x3", "attr_cmpval":"0x8", "attr_len":"1"} - ] } }, @@ -485,7 +483,6 @@ { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"}, { "attr_name":"xcvr_present", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x49", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"}, { "attr_name":"xcvr_rxlos", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x48", "attr_mask":"0x4", "attr_cmpval":"0x10", "attr_len":"1"} - ] } }, @@ -562,7 +559,7 @@ { "topo_info": { "parent_bus":"0x10", "dev_addr":"0x66", "dev_type":"pddf_xcvr"}, "attr_list": - [ + [ { "attr_name":"xcvr_txfault", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x47", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, { "attr_name":"xcvr_txdisable", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, { "attr_name":"xcvr_lpmode", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x4a", "attr_mask":"0x6", "attr_cmpval":"0x40", "attr_len":"1"}, @@ -622,9 +619,9 @@ "attr_list": [ { "attr_name":"fan1_pwm", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x32", "attr_mask":"0xff", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan2_pwm", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x36", "attr_mask":"0xff", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan3_pwm", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x3a", "attr_mask":"0xff", "attr_cmpval":"0x0", "attr_len":"1"}, - { "attr_name":"fan1_direction", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x88", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"fan2_pwm", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x36", "attr_mask":"0xff", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"fan3_pwm", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x3a", "attr_mask":"0xff", "attr_cmpval":"0x0", "attr_len":"1"}, + { "attr_name":"fan1_direction", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x88", "attr_mask":"0x4", "attr_cmpval":"0x0", "attr_len":"1"}, { "attr_name":"fan2_direction", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x88", "attr_mask":"0x2", "attr_cmpval":"0x0", "attr_len":"1"}, { "attr_name":"fan3_direction", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x88", "attr_mask":"0x1", "attr_cmpval":"0x0", "attr_len":"1"}, { "attr_name":"fan1_input", "attr_devaddr":"0x32", "attr_devtype":"cpld", "attr_devname":"CPLD1", "attr_offset":"0x31", "attr_mask":"0xff", "attr_len":"1", "attr_mult":"150", "attr_is_divisor":0}, @@ -640,9 +637,9 @@ "i2c" : { "attr_list": [ - {"attr_name":"STATUS_LED_COLOR_AMBER","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x1","swpld_addr_offset":"0x43"}, - {"attr_name":"STATUS_LED_COLOR_GREEN","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x2","swpld_addr_offset":"0x43"}, - {"attr_name":"STATUS_LED_COLOR_OFF","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x3","swpld_addr_offset":"0x43"} + {"attr_name":"amber","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x1","swpld_addr_offset":"0x43"}, + {"attr_name":"green","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x2","swpld_addr_offset":"0x43"}, + {"attr_name":"off","swpld_addr":"0x32","attr_devtype":"cpld","attr_devname":"CPLD1", "bits":"5:4","descr":"","value":"0x3","swpld_addr_offset":"0x43"} ] } }, @@ -653,8 +650,8 @@ "i2c" : { "attr_list": [ - {"attr_name":"STATUS_LED_COLOR_GREEN","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x33"}, - {"attr_name":"STATUS_LED_COLOR_AMBER","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x33"} + {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x33"}, + {"attr_name":"amber","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x33"} ] } }, @@ -665,8 +662,8 @@ "i2c" : { "attr_list": [ - {"attr_name":"STATUS_LED_COLOR_GREEN","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x37"}, - {"attr_name":"STATUS_LED_COLOR_AMBER","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x37"} + {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x37"}, + {"attr_name":"amber","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x37"} ] } }, @@ -677,8 +674,8 @@ "i2c" : { "attr_list": [ - {"attr_name":"STATUS_LED_COLOR_GREEN","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x3b"}, - {"attr_name":"STATUS_LED_COLOR_AMBER","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x3b"} + {"attr_name":"green","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x1","swpld_addr":"0x32","swpld_addr_offset":"0x3b"}, + {"attr_name":"amber","attr_devtype":"cpld","attr_devname":"CPLD1","bits":"1:0","descr":"","value":"0x2","swpld_addr":"0x32","swpld_addr_offset":"0x3b"} ] } } diff --git a/device/celestica/x86_64-cel_belgite-r0/pddf_support b/device/celestica/x86_64-cel_ds1000-r0/pddf_support similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/pddf_support rename to device/celestica/x86_64-cel_ds1000-r0/pddf_support diff --git a/device/celestica/x86_64-cel_belgite-r0/platform.json b/device/celestica/x86_64-cel_ds1000-r0/platform.json similarity index 62% rename from device/celestica/x86_64-cel_belgite-r0/platform.json rename to device/celestica/x86_64-cel_ds1000-r0/platform.json index 0e40fe8a88..79ae7f0bad 100644 --- a/device/celestica/x86_64-cel_belgite-r0/platform.json +++ b/device/celestica/x86_64-cel_ds1000-r0/platform.json @@ -1,94 +1,70 @@ { "chassis": { - "name": "E1070", + "name": "DS1000", "status_led": { "controllable": true, "colors": ["green", "amber", "off"] }, - "thermal_manager": false, + "thermal_manager": false, "components": [ - { - "name": "SWCPLD" - }, - { - "name": "BIOS" - } + { + "name": "CPLD SW" + }, + { + "name": "BIOS" + }, + { + "name": "ONIE" + }, + { + "name": "SSD" + } ], "fans": [ { - "name": "Fantray1_1", + "name": "Fan 1", "speed": { "controllable": true }, "status_led": { "controllable": true, - "colors": ["green", "amber","off"] + "colors": ["green", "amber", "off"] } }, { - "name": "Fantray2_1", + "name": "Fan 2", "speed": { "controllable": true }, "status_led": { "controllable": true, - "colors": ["green", "amber","off"] + "colors": ["green", "amber", "off"] } }, { - "name": "Fantray3_1", + "name": "Fan 3", "speed": { "controllable": true }, "status_led": { "controllable": true, - "colors": ["green", "amber","off"] - } - }, - { - "name": "Fantray1_1", - "speed": { - "controllable": true - }, - "status_led": { - "controllable": true, - "colors": ["green", "amber","off"] - } - }, - { - "name": "Fantray2_1", - "speed": { - "controllable": true - }, - "status_led": { - "controllable": true, - "colors": ["green", "amber","off"] - } - }, - { - "name": "Fantray3_1", - "speed": { - "controllable": true - }, - "status_led": { - "controllable": true, - "colors": ["green", "amber","off"] + "colors": ["green", "amber", "off"] } } ], "fan_drawers": [ { - "name": "Fantray1", + "name": "Drawer 1", "speed": { "controllable": false }, "status_led": { "controllable": false }, - "max_consumed_power": false, + "max_consumed_power": false, "fans": [ { - "name": "Fantray1_1", + "name": "Fan 1", "speed": { "controllable": false }, @@ -99,17 +75,17 @@ ] }, { - "name": "Fantray2", + "name": "Drawer 2", "speed": { "controllable": false }, "status_led": { "controllable": false }, - "max_consumed_power": false, + "max_consumed_power": false, "fans": [ { - "name": "Fantray2_1", + "name": "Fan 2", "speed": { "controllable": false }, @@ -120,17 +96,17 @@ ] }, { - "name": "Fantray3", + "name": "Drawer 3", "speed": { "controllable": false }, "status_led": { "controllable": false }, - "max_consumed_power": false, + "max_consumed_power": false, "fans": [ { - "name": "Fantray3_1", + "name": "Fan 3", "speed": { "controllable": false }, @@ -143,10 +119,10 @@ ], "psus": [ { - "name": "PSU1", + "name": "PSU 1", "fans": [ { - "name": "PSU1_FAN1", + "name": "PSU 1 Fan 1", "speed": { "controllable": false }, @@ -155,7 +131,7 @@ } } ], - "current": true, + "current": true, "power": true, "max_power": false, "voltage_high_threshold": false, @@ -167,10 +143,10 @@ } }, { - "name": "PSU2", + "name": "PSU 2", "fans": [ { - "name": "PSU2_FAN1", + "name": "PSU 2 Fan 1", "speed": { "controllable": false }, @@ -179,7 +155,7 @@ } } ], - "current": true, + "current": true, "power": true, "max_power": false, "voltage_high_threshold": false, @@ -193,175 +169,31 @@ ], "thermals": [ { - "name": "LM75_U10", + "name": "Front Left Temp", "controllable": false, "low-threshold": false, "low-crit-threshold": true }, { - "name": "LM75_U4", + "name": "Front Right Temp", "controllable": false, "low-threshold": false, "low-crit-threshold": true }, { - "name": "LM75_U7", + "name": "Rear Right Temp", "controllable": false, "low-threshold": false, "low-crit-threshold": true }, { - "name": "LM75_U60", + "name": "ASIC External Temp", "controllable": false, "low-threshold": false, "low-crit-threshold": true } ], "sfps": [ - { - "name": "PORT0" - }, - { - "name": "PORT1" - }, - { - "name": "PORT2" - }, - { - "name": "PORT3" - }, - { - "name": "PORT4" - }, - { - "name": "PORT5" - }, - { - "name": "PORT6" - }, - { - "name": "PORT7" - }, - { - "name": "PORT8" - }, - { - "name": "PORT9" - }, - { - "name": "PORT10" - }, - { - "name": "PORT11" - }, - { - "name": "PORT12" - }, - { - "name": "PORT13" - }, - { - "name": "PORT14" - }, - { - "name": "PORT15" - }, - { - "name": "PORT16" - }, - { - "name": "PORT17" - }, - { - "name": "PORT18" - }, - { - "name": "PORT19" - }, - { - "name": "PORT20" - }, - { - "name": "PORT21" - }, - { - "name": "PORT22" - }, - { - "name": "PORT23" - }, - { - "name": "PORT24" - }, - { - "name": "PORT25" - }, - { - "name": "PORT26" - }, - { - "name": "PORT27" - }, - { - "name": "PORT28" - }, - { - "name": "PORT29" - }, - { - "name": "PORT30" - }, - { - "name": "PORT31" - }, - { - "name": "PORT32" - }, - { - "name": "PORT33" - }, - { - "name": "PORT34" - }, - { - "name": "PORT35" - }, - { - "name": "PORT36" - }, - { - "name": "PORT37" - }, - { - "name": "PORT38" - }, - { - "name": "PORT39" - }, - { - "name": "PORT40" - }, - { - "name": "PORT41" - }, - { - "name": "PORT42" - }, - { - "name": "PORT43" - }, - { - "name": "PORT44" - }, - { - "name": "PORT45" - }, - { - "name": "PORT46" - }, - { - "name": "PORT47" - }, { "name": "PORT48" }, @@ -393,392 +225,392 @@ "index": "1", "lanes": "26", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/1"] + "1x1000[100,10]": ["Eth1/1"] } }, "Ethernet1": { "index": "2", "lanes": "25", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/2"] + "1x1000[100,10]": ["Eth2/1"] } }, "Ethernet2": { "index": "3", "lanes": "28", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/3"] + "1x1000[100,10]": ["Eth3/1"] } }, "Ethernet3": { "index": "4", "lanes": "27", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/4"] + "1x1000[100,10]": ["Eth4/1"] } }, "Ethernet4": { "index": "5", "lanes": "30", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/5"] + "1x1000[100,10]": ["Eth5/1"] } }, "Ethernet5": { "index": "6", "lanes": "29", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/6"] + "1x1000[100,10]": ["Eth6/1"] } }, "Ethernet6": { "index": "7", "lanes": "32", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/7"] + "1x1000[100,10]": ["Eth7/1"] } }, "Ethernet7": { "index": "8", "lanes": "31", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/8"] + "1x1000[100,10]": ["Eth8/1"] } }, "Ethernet8": { "index": "9", "lanes": "34", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/9"] + "1x1000[100,10]": ["Eth9/1"] } }, "Ethernet9": { "index": "10", "lanes": "33", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/10"] + "1x1000[100,10]": ["Eth10/1"] } }, "Ethernet10": { "index": "11", "lanes": "36", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/11"] + "1x1000[100,10]": ["Eth11/1"] } }, "Ethernet11": { "index": "12", "lanes": "35", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/12"] + "1x1000[100,10]": ["Eth12/1"] } }, "Ethernet12": { "index": "13", "lanes": "38", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/13"] + "1x1000[100,10]": ["Eth13/1"] } }, "Ethernet13": { "index": "14", "lanes": "37", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/14"] + "1x1000[100,10]": ["Eth14/1"] } }, "Ethernet14": { "index": "15", "lanes": "40", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/15"] + "1x1000[100,10]": ["Eth15/1"] } }, "Ethernet15": { "index": "16", "lanes": "39", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/16"] + "1x1000[100,10]": ["Eth16/1"] } }, "Ethernet16": { "index": "17", "lanes": "42", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/17"] + "1x1000[100,10]": ["Eth17/1"] } }, "Ethernet17": { "index": "18", "lanes": "41", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/18"] + "1x1000[100,10]": ["Eth18/1"] } }, "Ethernet18": { "index": "19", "lanes": "44", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/19"] + "1x1000[100,10]": ["Eth19/1"] } }, "Ethernet19": { "index": "20", "lanes": "43", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/20"] + "1x1000[100,10]": ["Eth20/1"] } }, "Ethernet20": { "index": "21", "lanes": "50", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/21"] + "1x1000[100,10]": ["Eth21/1"] } }, "Ethernet21": { "index": "22", "lanes": "49", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/22"] + "1x1000[100,10]": ["Eth22/1"] } }, "Ethernet22": { "index": "23", "lanes": "52", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/23"] + "1x1000[100,10]": ["Eth23/1"] } }, "Ethernet23": { "index": "24", "lanes": "51", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/24"] + "1x1000[100,10]": ["Eth24/1"] } }, "Ethernet24": { "index": "25", "lanes": "2", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/25"] + "1x1000[100,10]": ["Eth25/1"] } }, "Ethernet25": { "index": "26", "lanes": "1", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/26"] + "1x1000[100,10]": ["Eth26/1"] } }, "Ethernet26": { "index": "27", "lanes": "4", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/27"] + "1x1000[100,10]": ["Eth27/1"] } }, "Ethernet27": { "index": "28", "lanes": "3", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/28"] + "1x1000[100,10]": ["Eth28/1"] } }, "Ethernet28": { "index": "29", "lanes": "6", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/29"] + "1x1000[100,10]": ["Eth29/1"] } }, "Ethernet29": { "index": "30", "lanes": "5", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/30"] + "1x1000[100,10]": ["Eth30/1"] } }, "Ethernet30": { "index": "31", "lanes": "8", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/31"] + "1x1000[100,10]": ["Eth31/1"] } }, "Ethernet31": { "index": "32", "lanes": "7", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/32"] + "1x1000[100,10]": ["Eth32/1"] } }, "Ethernet32": { "index": "33", "lanes": "10", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/33"] + "1x1000[100,10]": ["Eth33/1"] } }, "Ethernet33": { "index": "34", "lanes": "9", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/34"] + "1x1000[100,10]": ["Eth34/1"] } }, "Ethernet34": { "index": "35", "lanes": "12", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/35"] + "1x1000[100,10]": ["Eth35/1"] } }, "Ethernet35": { "index": "36", "lanes": "11", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/36"] + "1x1000[100,10]": ["Eth36/1"] } }, "Ethernet36": { "index": "37", "lanes": "14", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/37"] + "1x1000[100,10]": ["Eth37/1"] } }, "Ethernet37": { "index": "38", "lanes": "13", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/38"] + "1x1000[100,10]": ["Eth38/1"] } }, "Ethernet38": { "index": "39", "lanes": "16", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/39"] + "1x1000[100,10]": ["Eth39/1"] } }, "Ethernet39": { "index": "40", "lanes": "15", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/40"] + "1x1000[100,10]": ["Eth40/1"] } }, "Ethernet40": { "index": "41", "lanes": "18", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/41"] + "1x1000[100,10]": ["Eth41/1"] } }, "Ethernet41": { "index": "42", "lanes": "17", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/42"] + "1x1000[100,10]": ["Eth42/1"] } }, "Ethernet42": { "index": "43", "lanes": "20", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/43"] + "1x1000[100,10]": ["Eth43/1"] } }, "Ethernet43": { "index": "44", "lanes": "19", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/44"] + "1x1000[100,10]": ["Eth44/1"] } }, "Ethernet44": { "index": "45", "lanes": "22", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/45"] + "1x1000[100,10]": ["Eth45/1"] } }, "Ethernet45": { "index": "46", "lanes": "21", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/46"] + "1x1000[100,10]": ["Eth46/1"] } }, "Ethernet46": { "index": "47", "lanes": "24", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/47"] + "1x1000[100,10]": ["Eth47/1"] } }, "Ethernet47": { "index": "48", "lanes": "23", "breakout_modes": { - "1x1000[100,10]": ["Ethernet1/0/48"] + "1x1000[100,10]": ["Eth48/1"] } }, "Ethernet48": { "index": "49", "lanes": "60", "breakout_modes": { - "1x10G[1G]": ["Ethernet1/0/49"] + "1x10G[1G]": ["Eth49/1"] } }, "Ethernet49": { "index": "50", "lanes": "58", "breakout_modes": { - "1x10G[1G]": ["Ethernet1/0/50"] + "1x10G[1G]": ["Eth50/1"] } }, "Ethernet50": { "index": "51", "lanes": "59", "breakout_modes": { - "1x10G[1G]": ["Ethernet1/0/51"] + "1x10G[1G]": ["Eth51/1"] } }, "Ethernet51": { "index": "52", "lanes": "57", "breakout_modes": { - "1x10G[1G]": ["Ethernet1/0/52"] + "1x10G[1G]": ["Eth52/1"] } }, "Ethernet52": { "index": "53", "lanes": "62", "breakout_modes": { - "1x10G[1G]": ["Ethernet1/0/53"] + "1x10G[1G]": ["Eth53/1"] } }, "Ethernet53": { "index": "54", "lanes": "64", "breakout_modes": { - "1x10G[1G]": ["Ethernet1/0/54"] + "1x10G[1G]": ["Eth54/1"] } }, "Ethernet54": { "index": "55", "lanes": "61", "breakout_modes": { - "1x10G[1G]": ["Ethernet1/0/55"] + "1x10G[1G]": ["Eth55/1"] } }, "Ethernet55": { "index": "56", "lanes": "63", "breakout_modes": { - "1x10G[1G]": ["Ethernet1/0/56"] + "1x10G[1G]": ["Eth56/1"] } } } diff --git a/device/celestica/x86_64-cel_belgite-r0/platform_asic b/device/celestica/x86_64-cel_ds1000-r0/platform_asic similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/platform_asic rename to device/celestica/x86_64-cel_ds1000-r0/platform_asic diff --git a/device/celestica/x86_64-cel_ds1000-r0/platform_components.json b/device/celestica/x86_64-cel_ds1000-r0/platform_components.json new file mode 100644 index 0000000000..deeabc3dee --- /dev/null +++ b/device/celestica/x86_64-cel_ds1000-r0/platform_components.json @@ -0,0 +1,12 @@ +{ + "chassis": { + "DS1000": { + "component": { + "BIOS": {}, + "ONIE": {}, + "CPLD SW": {}, + "SSD": {} + } + } + } +} diff --git a/device/celestica/x86_64-cel_ds1000-r0/platform_reboot b/device/celestica/x86_64-cel_ds1000-r0/platform_reboot new file mode 100755 index 0000000000..233af9d085 --- /dev/null +++ b/device/celestica/x86_64-cel_ds1000-r0/platform_reboot @@ -0,0 +1,3 @@ +#!/bin/bash + +/usr/local/bin/ds1000_platform_shutdown.sh system diff --git a/device/celestica/x86_64-cel_belgite-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_ds1000-r0/plugins/eeprom.py similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/plugins/eeprom.py rename to device/celestica/x86_64-cel_ds1000-r0/plugins/eeprom.py diff --git a/device/celestica/x86_64-cel_belgite-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_ds1000-r0/plugins/psuutil.py similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/plugins/psuutil.py rename to device/celestica/x86_64-cel_ds1000-r0/plugins/psuutil.py diff --git a/device/celestica/x86_64-cel_belgite-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_ds1000-r0/plugins/sfputil.py similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/plugins/sfputil.py rename to device/celestica/x86_64-cel_ds1000-r0/plugins/sfputil.py diff --git a/device/celestica/x86_64-cel_belgite-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_ds1000-r0/pmon_daemon_control.json similarity index 100% rename from device/celestica/x86_64-cel_belgite-r0/pmon_daemon_control.json rename to device/celestica/x86_64-cel_ds1000-r0/pmon_daemon_control.json diff --git a/device/celestica/x86_64-cel_ds1000-r0/sensors.conf b/device/celestica/x86_64-cel_ds1000-r0/sensors.conf new file mode 100644 index 0000000000..aeb82af7ea --- /dev/null +++ b/device/celestica/x86_64-cel_ds1000-r0/sensors.conf @@ -0,0 +1,45 @@ +# libsensors configuration file for Celestica DS1000 + +bus "i2c-6" "i2c-0-mux (chan_id 4)" +bus "i2c-4" "i2c-0-mux (chan_id 2)" +bus "i2c-2" "i2c-0-mux (chan_id 0)" +bus "i2c-5" "i2c-0-mux (chan_id 3)" + +chip "fan_cpld-i2c-2-66" + label fan1 "Fantray1_1 speed" + label fan2 "Fantray2_1 speed" + label fan3 "Fantray3_1 speed" + +chip "psu_pmbus-i2c-4-58" + label fan1 "PSU1 fan speed" + label in3 "PSU1 output voltage" + label temp1 "PSU1 temperature" + label power2 "PSU1 output power" + label curr2 "PSU1 output current" + +chip "psu_pmbus-i2c-4-59" + label fan1 "PSU2 fan speed" + label in3 "PSU2 output voltage" + label temp1 "PSU2 temperature" + label power2 "PSU2 output power" + label curr2 "PSU2 output current" + +chip "lm75-i2c-5-48" + label temp1 "Front Left Temp" + set temp1_max 50 + set temp1_max_hyst 45 + +chip "lm75-i2c-5-49" + label temp1 "Front Right Temp" + set temp1_max 50 + set temp1_max_hyst 45 + +chip "lm75-i2c-6-4a" + label temp1 "Rear Right Temp" + set temp1_max 50 + set temp1_max_hyst 45 + +chip "lm75-i2c-6-49" + set temp1_max 110 + set temp1_max_hyst 105 + label temp1 "ASIC External Temp" diff --git a/device/celestica/x86_64-cel_belgite-r0/system_health_monitoring_config.json b/device/celestica/x86_64-cel_ds1000-r0/system_health_monitoring_config.json similarity index 86% rename from device/celestica/x86_64-cel_belgite-r0/system_health_monitoring_config.json rename to device/celestica/x86_64-cel_ds1000-r0/system_health_monitoring_config.json index 28b3e30a66..6f7d70895a 100644 --- a/device/celestica/x86_64-cel_belgite-r0/system_health_monitoring_config.json +++ b/device/celestica/x86_64-cel_ds1000-r0/system_health_monitoring_config.json @@ -3,8 +3,8 @@ "devices_to_ignore": [ "asic", "psu.temperature", - "PSU1_FAN1", - "PSU2_FAN1" + "PSU 1 Fan 1", + "PSU 2 Fan 1" ], "user_defined_checkers": [], "polling_interval": 60, diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2/custom_led.bin b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/custom_led.bin new file mode 100644 index 0000000000000000000000000000000000000000..b2ed8cb8d09014028181c580ddaaafa943990585 GIT binary patch literal 248 zcmeycHQp`E&DYJv?ZXx>232oK1`ESZHwKjk#SS-SH6_n3Hzq|vhaNZiiYmED46GTU z(MAl8ZkkR47n(9INitdqRj^uJ+{B{EdZUXW(5)+Cx*L-c(*q+0h6jvFdQQw265SXy z87>$xxMpYtGa9p)c)Q-b$f$TQfkBx$QCi69)viwcCfi2i(?JFfcp;VnZWi6J9=k0Z}n=30XOL1w|!g6-_N|9Y!W*7FITP mj?l31h}gLJgv6xel+3K`9825E!dgdP*C?RgARq?OFg5^j6GYhn literal 0 HcmV?d00001 diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2/hwsku.json b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/hwsku.json new file mode 100644 index 0000000000..a559890f3a --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/hwsku.json @@ -0,0 +1,284 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet2": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet3": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet4": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet5": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet6": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet7": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet9": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet10": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet11": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet12": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet13": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet14": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet15": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet17": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet18": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet19": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet20": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet21": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet22": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet23": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet25": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet26": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet27": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet28": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet29": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet30": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet31": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet33": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet34": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet35": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet36": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet37": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet38": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet39": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet41": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet42": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet43": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet44": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet45": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet46": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet47": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2/platform.json b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/platform.json new file mode 100644 index 0000000000..0805efbc7b --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/platform.json @@ -0,0 +1,396 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1", + "lanes": "49", + "breakout_modes": { + "1x25G": ["Eth1/1"] + } + }, + "Ethernet1": { + "index": "2", + "lanes": "50", + "breakout_modes": { + "1x25G": ["Eth2/1"] + } + }, + "Ethernet2": { + "index": "3", + "lanes": "51", + "breakout_modes": { + "1x25G": ["Eth3/1"] + } + }, + "Ethernet3": { + "index": "4", + "lanes": "52", + "breakout_modes": { + "1x25G": ["Eth4/1"] + } + }, + "Ethernet4": { + "index": "5", + "lanes": "57", + "breakout_modes": { + "1x25G": ["Eth5/1"] + } + }, + "Ethernet5": { + "index": "6", + "lanes": "58", + "breakout_modes": { + "1x25G": ["Eth6/1"] + } + }, + "Ethernet6": { + "index": "7", + "lanes": "59", + "breakout_modes": { + "1x25G": ["Eth7/1"] + } + }, + "Ethernet7": { + "index": "8", + "lanes": "60", + "breakout_modes": { + "1x25G": ["Eth8/1"] + } + }, + "Ethernet8": { + "index": "9", + "lanes": "61", + "breakout_modes": { + "1x25G": ["Eth9/1"] + } + }, + "Ethernet9": { + "index": "10", + "lanes": "62", + "breakout_modes": { + "1x25G": ["Eth10/1"] + } + }, + "Ethernet10": { + "index": "11", + "lanes": "63", + "breakout_modes": { + "1x25G": ["Eth11/1"] + } + }, + "Ethernet11": { + "index": "12", + "lanes": "64", + "breakout_modes": { + "1x25G": ["Eth12/1"] + } + }, + "Ethernet12": { + "index": "13", + "lanes": "77", + "breakout_modes": { + "1x25G": ["Eth13/1"] + } + }, + "Ethernet13": { + "index": "14", + "lanes": "78", + "breakout_modes": { + "1x25G": ["Eth14/1"] + } + }, + "Ethernet14": { + "index": "15", + "lanes": "79", + "breakout_modes": { + "1x25G": ["Eth15/1"] + } + }, + "Ethernet15": { + "index": "16", + "lanes": "80", + "breakout_modes": { + "1x25G": ["Eth16/1"] + } + }, + "Ethernet16": { + "index": "17", + "lanes": "85", + "breakout_modes": { + "1x25G": ["Eth17/1"] + } + }, + "Ethernet17": { + "index": "18", + "lanes": "86", + "breakout_modes": { + "1x25G": ["Eth18/1"] + } + }, + "Ethernet18": { + "index": "19", + "lanes": "87", + "breakout_modes": { + "1x25G": ["Eth19/1"] + } + }, + "Ethernet19": { + "index": "20", + "lanes": "88", + "breakout_modes": { + "1x25G": ["Eth20/1"] + } + }, + "Ethernet20": { + "index": "21", + "lanes": "93", + "breakout_modes": { + "1x25G": ["Eth21/1"] + } + }, + "Ethernet21": { + "index": "22", + "lanes": "94", + "breakout_modes": { + "1x25G": ["Eth22/1"] + } + }, + "Ethernet22": { + "index": "23", + "lanes": "95", + "breakout_modes": { + "1x25G": ["Eth23/1"] + } + }, + "Ethernet23": { + "index": "24", + "lanes": "96", + "breakout_modes": { + "1x25G": ["Eth24/1"] + } + }, + "Ethernet24": { + "index": "25", + "lanes": "13", + "breakout_modes": { + "1x25G": ["Eth25/1"] + } + }, + "Ethernet25": { + "index": "26", + "lanes": "14", + "breakout_modes": { + "1x25G": ["Eth26/1"] + } + }, + "Ethernet26": { + "index": "27", + "lanes": "15", + "breakout_modes": { + "1x25G": ["Eth27/1"] + } + }, + "Ethernet27": { + "index": "28", + "lanes": "16", + "breakout_modes": { + "1x25G": ["Eth28/1"] + } + }, + "Ethernet28": { + "index": "29", + "lanes": "21", + "breakout_modes": { + "1x25G": ["Eth29/1"] + } + }, + "Ethernet29": { + "index": "30", + "lanes": "22", + "breakout_modes": { + "1x25G": ["Eth30/1"] + } + }, + "Ethernet30": { + "index": "31", + "lanes": "23", + "breakout_modes": { + "1x25G": ["Eth31/1"] + } + }, + "Ethernet31": { + "index": "32", + "lanes": "24", + "breakout_modes": { + "1x25G": ["Eth32/1"] + } + }, + "Ethernet32": { + "index": "33", + "lanes": "29", + "breakout_modes": { + "1x25G": ["Eth33/1"] + } + }, + "Ethernet33": { + "index": "34", + "lanes": "30", + "breakout_modes": { + "1x25G": ["Eth34/1"] + } + }, + "Ethernet34": { + "index": "35", + "lanes": "31", + "breakout_modes": { + "1x25G": ["Eth35/1"] + } + }, + "Ethernet35": { + "index": "36", + "lanes": "32", + "breakout_modes": { + "1x25G": ["Eth36/1"] + } + }, + "Ethernet36": { + "index": "37", + "lanes": "97", + "breakout_modes": { + "1x25G": ["Eth37/1"] + } + }, + "Ethernet37": { + "index": "38", + "lanes": "98", + "breakout_modes": { + "1x25G": ["Eth38/1"] + } + }, + "Ethernet38": { + "index": "39", + "lanes": "99", + "breakout_modes": { + "1x25G": ["Eth39/1"] + } + }, + "Ethernet39": { + "index": "40", + "lanes": "100", + "breakout_modes": { + "1x25G": ["Eth40/1"] + } + }, + "Ethernet40": { + "index": "41", + "lanes": "105", + "breakout_modes": { + "1x25G": ["Eth41/1"] + } + }, + "Ethernet41": { + "index": "42", + "lanes": "106", + "breakout_modes": { + "1x25G": ["Eth42/1"] + } + }, + "Ethernet42": { + "index": "43", + "lanes": "107", + "breakout_modes": { + "1x25G": ["Eth43/1"] + } + }, + "Ethernet43": { + "index": "44", + "lanes": "108", + "breakout_modes": { + "1x25G": ["Eth44/1"] + } + }, + "Ethernet44": { + "index": "45", + "lanes": "113", + "breakout_modes": { + "1x25G": ["Eth45/1"] + } + }, + "Ethernet45": { + "index": "46", + "lanes": "114", + "breakout_modes": { + "1x25G": ["Eth46/1"] + } + }, + "Ethernet46": { + "index": "47", + "lanes": "115", + "breakout_modes": { + "1x25G": ["Eth47/1"] + } + }, + "Ethernet47": { + "index": "48", + "lanes": "116", + "breakout_modes": { + "1x25G": ["Eth48/1"] + } + }, + "Ethernet48": { + "index": "49,49,49,49", + "lanes": "65,66,67,68", + "breakout_modes": { + "1x100G": ["Eth49/1"] + } + }, + "Ethernet52": { + "index": "50,50,50,50", + "lanes": "69,70,71,72", + "breakout_modes": { + "1x100G": ["Eth50/1"] + } + }, + "Ethernet56": { + "index": "51,51,51,51", + "lanes": "121,122,123,124", + "breakout_modes": { + "1x100G": ["Eth51/1"] + } + }, + "Ethernet60": { + "index": "52,52,52,52", + "lanes": "125,126,127,128", + "breakout_modes": { + "1x100G": ["Eth52/1"] + } + }, + "Ethernet64": { + "index": "53,53,53,53", + "lanes": "1,2,3,4", + "breakout_modes": { + "1x100G": ["Eth53/1"] + } + }, + "Ethernet68": { + "index": "54,54,54,54", + "lanes": "33,34,35,36", + "breakout_modes": { + "1x100G": ["Eth54/1"] + } + }, + "Ethernet72": { + "index": "55,55,55,55", + "lanes": "5,6,7,8", + "breakout_modes": { + "1x100G": ["Eth55/1"] + } + }, + "Ethernet76": { + "index": "56,56,56,56", + "lanes": "41,42,43,44", + "breakout_modes": { + "1x100G": ["Eth56/1"] + } + } + } +} diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2/platform_components.json b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/platform_components.json new file mode 100644 index 0000000000..b86899e311 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/platform_components.json @@ -0,0 +1,17 @@ +{ + "chassis": { + "Questone_2": { + "component": { + "BIOS": {}, + "ONIE": {}, + "BMC": {}, + "FPGA": {}, + "CPLD COMe": {}, + "CPLD BASE": {}, + "CPLD SW1": {}, + "CPLD SW2": {}, + "SSD": {} + } + } + } +} diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2/port_config.ini b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/port_config.ini new file mode 100644 index 0000000000..37c4f0cfd0 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed mtu admin_status fec +Ethernet0 49 Eth1/1 1 25000 9216 up rs +Ethernet1 50 Eth2/1 2 25000 9216 up rs +Ethernet2 51 Eth3/1 3 25000 9216 up rs +Ethernet3 52 Eth4/1 4 25000 9216 up rs +Ethernet4 57 Eth5/1 5 25000 9216 up rs +Ethernet5 58 Eth6/1 6 25000 9216 up rs +Ethernet6 59 Eth7/1 7 25000 9216 up rs +Ethernet7 60 Eth8/1 8 25000 9216 up rs +Ethernet8 61 Eth9/1 9 25000 9216 up rs +Ethernet9 62 Eth10/1 10 25000 9216 up rs +Ethernet10 63 Eth11/1 11 25000 9216 up rs +Ethernet11 64 Eth12/1 12 25000 9216 up rs +Ethernet12 77 Eth13/1 13 25000 9216 up rs +Ethernet13 78 Eth14/1 14 25000 9216 up rs +Ethernet14 79 Eth15/1 15 25000 9216 up rs +Ethernet15 80 Eth16/1 16 25000 9216 up rs +Ethernet16 85 Eth17/1 17 25000 9216 up rs +Ethernet17 86 Eth18/1 18 25000 9216 up rs +Ethernet18 87 Eth19/1 19 25000 9216 up rs +Ethernet19 88 Eth20/1 20 25000 9216 up rs +Ethernet20 93 Eth21/1 21 25000 9216 up rs +Ethernet21 94 Eth22/1 22 25000 9216 up rs +Ethernet22 95 Eth23/1 23 25000 9216 up rs +Ethernet23 96 Eth24/1 24 25000 9216 up rs +Ethernet24 13 Eth25/1 25 25000 9216 up rs +Ethernet25 14 Eth26/1 26 25000 9216 up rs +Ethernet26 15 Eth27/1 27 25000 9216 up rs +Ethernet27 16 Eth28/1 28 25000 9216 up rs +Ethernet28 21 Eth29/1 29 25000 9216 up rs +Ethernet29 22 Eth30/1 30 25000 9216 up rs +Ethernet30 23 Eth31/1 31 25000 9216 up rs +Ethernet31 24 Eth32/1 32 25000 9216 up rs +Ethernet32 29 Eth33/1 33 25000 9216 up rs +Ethernet33 30 Eth34/1 34 25000 9216 up rs +Ethernet34 31 Eth35/1 35 25000 9216 up rs +Ethernet35 32 Eth36/1 36 25000 9216 up rs +Ethernet36 97 Eth37/1 37 25000 9216 up rs +Ethernet37 98 Eth38/1 38 25000 9216 up rs +Ethernet38 99 Eth39/1 39 25000 9216 up rs +Ethernet39 100 Eth40/1 40 25000 9216 up rs +Ethernet40 105 Eth41/1 41 25000 9216 up rs +Ethernet41 106 Eth42/1 42 25000 9216 up rs +Ethernet42 107 Eth43/1 43 25000 9216 up rs +Ethernet43 108 Eth44/1 44 25000 9216 up rs +Ethernet44 113 Eth45/1 45 25000 9216 up rs +Ethernet45 114 Eth46/1 46 25000 9216 up rs +Ethernet46 115 Eth47/1 47 25000 9216 up rs +Ethernet47 116 Eth48/1 48 25000 9216 up rs +Ethernet48 65,66,67,68 Eth49/1 49 100000 9216 up rs +Ethernet52 69,70,71,72 Eth50/1 50 100000 9216 up rs +Ethernet56 121,122,123,124 Eth51/1 51 100000 9216 up rs +Ethernet60 125,126,127,128 Eth52/1 52 100000 9216 up rs +Ethernet64 1,2,3,4 Eth53/1 53 100000 9216 up rs +Ethernet68 33,34,35,36 Eth54/1 54 100000 9216 up rs +Ethernet72 5,6,7,8 Eth55/1 55 100000 9216 up rs +Ethernet76 41,42,43,44 Eth56/1 56 100000 9216 up rs diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2/sai.profile b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/sai.profile new file mode 100644 index 0000000000..636d9d72fc --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/sai.profile @@ -0,0 +1 @@ +SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as13-48f8h.config.bcm diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2/td3-as13-48f8h.config.bcm b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/td3-as13-48f8h.config.bcm new file mode 100644 index 0000000000..3fe4e4395b --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2/td3-as13-48f8h.config.bcm @@ -0,0 +1,357 @@ +help_cli_enable=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=0x1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_max_ecmp_mode=1 +l3_mem_entries=49152 +l3_alpm_enable=2 +bcm_stat_interval=1000000 +host_as_route_disable=1 +lpm_scaling_enable=1 +max_vp_lags=0 +mem_cache_enable=0 +memlist_enable=1 +miim_intr_enable=0 +module_64ports=1 +oversubscribe_mode=1 +parity_enable=1 +serdes_lane_config_dfe=on +#serdes_fec_enable=1 +serdes_if_type_xe=13 +serdes_if_type_ce=14 +pbmp_gport_stack.0=0x0000000000000000000000000000000000000000000000000000000000000000 +#pbmp_xport_xe=0x48878787f8787808dfe1e0203e1e1e022 +pbmp_xport_xe=0x8808787f87808088221e1e1fe1e1e1fe + + +portmap_1.0=1:100 +portmap_5.0=5:100 +portmap_13.0=13:25 +portmap_14.0=14:25 +portmap_15.0=15:25 +portmap_16.0=16:25 +portmap_21.0=21:25 +portmap_22.0=22:25 +portmap_23.0=23:25 +portmap_24.0=24:25 +portmap_29.0=29:25 +portmap_30.0=30:25 +portmap_31.0=31:25 +portmap_32.0=32:25 +portmap_33.0=33:100 +portmap_41.0=41:100 +portmap_49.0=49:25 +portmap_50.0=50:25 +portmap_51.0=51:25 +portmap_52.0=52:25 +portmap_57.0=57:25 +portmap_58.0=58:25 +portmap_59.0=59:25 +portmap_60.0=60:25 +portmap_61.0=61:25 +portmap_62.0=62:25 +portmap_63.0=63:25 +portmap_64.0=64:25 +portmap_67.0=65:100 +portmap_71.0=69:100 +portmap_79.0=77:25 +portmap_80.0=78:25 +portmap_81.0=79:25 +portmap_82.0=80:25 +portmap_87.0=85:25 +portmap_88.0=86:25 +portmap_89.0=87:25 +portmap_90.0=88:25 +portmap_95.0=93:25 +portmap_96.0=94:25 +portmap_97.0=95:25 +portmap_98.0=96:25 +portmap_99.0=97:25 +portmap_100.0=98:25 +portmap_101.0=99:25 +portmap_102.0=100:25 +portmap_107.0=105:25 +portmap_108.0=106:25 +portmap_109.0=107:25 +portmap_110.0=108:25 +portmap_115.0=113:25 +portmap_116.0=114:25 +portmap_117.0=115:25 +portmap_118.0=116:25 +portmap_123.0=121:100 +portmap_127.0=125:100 + +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1302 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_tx_lane_map_physical{21.0}=0x0123 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x1302 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x3120 +phy_chain_rx_lane_map_physical{41.0}=0x1032 +phy_chain_tx_lane_map_physical{49.0}=0x0123 +phy_chain_rx_lane_map_physical{49.0}=0x1032 +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x1032 +phy_chain_tx_lane_map_physical{61.0}=0x0123 +phy_chain_rx_lane_map_physical{61.0}=0x1032 +phy_chain_tx_lane_map_physical{65.0}=0x1302 +phy_chain_rx_lane_map_physical{65.0}=0x1023 +phy_chain_tx_lane_map_physical{69.0}=0x1032 +phy_chain_rx_lane_map_physical{69.0}=0x0213 +phy_chain_tx_lane_map_physical{77.0}=0x3210 +phy_chain_rx_lane_map_physical{77.0}=0x2301 +phy_chain_tx_lane_map_physical{85.0}=0x3210 +phy_chain_rx_lane_map_physical{85.0}=0x2301 +phy_chain_tx_lane_map_physical{93.0}=0x3210 +phy_chain_rx_lane_map_physical{93.0}=0x2301 +phy_chain_tx_lane_map_physical{97.0}=0x3210 +phy_chain_rx_lane_map_physical{97.0}=0x2301 +phy_chain_tx_lane_map_physical{105.0}=0x3210 +phy_chain_rx_lane_map_physical{105.0}=0x2301 +phy_chain_tx_lane_map_physical{113.0}=0x3210 +phy_chain_rx_lane_map_physical{113.0}=0x2301 +phy_chain_tx_lane_map_physical{121.0}=0x2301 +phy_chain_rx_lane_map_physical{121.0}=0x2031 +phy_chain_tx_lane_map_physical{125.0}=0x0132 +phy_chain_rx_lane_map_physical{125.0}=0x3012 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x1 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x0 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 +phy_chain_tx_polarity_flip_physical{29.0}=0x0 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x1 +phy_chain_tx_polarity_flip_physical{32.0}=0x1 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x1 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 +phy_chain_tx_polarity_flip_physical{41.0}=0x0 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x1 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x0 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x0 +phy_chain_rx_polarity_flip_physical{50.0}=0x1 +phy_chain_tx_polarity_flip_physical{51.0}=0x1 +phy_chain_rx_polarity_flip_physical{51.0}=0x0 +phy_chain_tx_polarity_flip_physical{52.0}=0x0 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x0 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x1 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x0 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x1 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 +phy_chain_tx_polarity_flip_physical{69.0}=0x0 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x1 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x0 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x1 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x1 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 +phy_chain_tx_polarity_flip_physical{85.0}=0x0 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x1 +phy_chain_rx_polarity_flip_physical{86.0}=0x0 +phy_chain_tx_polarity_flip_physical{87.0}=0x0 +phy_chain_rx_polarity_flip_physical{87.0}=0x1 +phy_chain_tx_polarity_flip_physical{88.0}=0x1 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 +phy_chain_tx_polarity_flip_physical{93.0}=0x0 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x0 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x1 +phy_chain_tx_polarity_flip_physical{96.0}=0x1 +phy_chain_rx_polarity_flip_physical{96.0}=0x0 +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x0 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x1 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x1 +phy_chain_tx_polarity_flip_physical{121.0}=0x0 +phy_chain_rx_polarity_flip_physical{121.0}=0x1 +phy_chain_tx_polarity_flip_physical{122.0}=0x1 +phy_chain_rx_polarity_flip_physical{122.0}=0x0 +phy_chain_tx_polarity_flip_physical{123.0}=0x0 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x1 +phy_chain_rx_polarity_flip_physical{124.0}=0x0 +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x0 +phy_chain_tx_polarity_flip_physical{126.0}=0x1 +phy_chain_rx_polarity_flip_physical{126.0}=0x1 +phy_chain_tx_polarity_flip_physical{127.0}=0x0 +phy_chain_rx_polarity_flip_physical{127.0}=0x0 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +#MC P/N flip +phy_chain_tx_polarity_flip_physical{129.0}=0x0 +phy_chain_rx_polarity_flip_physical{129.0}=0x1 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x1 + +dport_map_port_49=1 +dport_map_port_50=2 +dport_map_port_51=3 +dport_map_port_52=4 +dport_map_port_57=5 +dport_map_port_58=6 +dport_map_port_59=7 +dport_map_port_60=8 +dport_map_port_61=9 +dport_map_port_62=10 +dport_map_port_63=11 +dport_map_port_64=12 +dport_map_port_79=13 +dport_map_port_80=14 +dport_map_port_81=15 +dport_map_port_82=16 +dport_map_port_87=17 +dport_map_port_88=18 +dport_map_port_89=19 +dport_map_port_90=20 +dport_map_port_95=21 +dport_map_port_96=22 +dport_map_port_97=23 +dport_map_port_98=24 +dport_map_port_13=25 +dport_map_port_14=26 +dport_map_port_15=27 +dport_map_port_16=28 +dport_map_port_21=29 +dport_map_port_22=30 +dport_map_port_23=31 +dport_map_port_24=32 +dport_map_port_29=33 +dport_map_port_30=34 +dport_map_port_31=35 +dport_map_port_32=36 +dport_map_port_99=37 +dport_map_port_100=38 +dport_map_port_101=39 +dport_map_port_102=40 +dport_map_port_107=41 +dport_map_port_108=42 +dport_map_port_109=43 +dport_map_port_110=44 +dport_map_port_115=45 +dport_map_port_116=46 +dport_map_port_117=47 +dport_map_port_118=48 +dport_map_port_67=49 +dport_map_port_71=50 +dport_map_port_123=51 +dport_map_port_127=52 +dport_map_port_1=53 +dport_map_port_33=54 +dport_map_port_5=55 +dport_map_port_41=56 + +reglist_enable=1 +scache_filename=/tmp/scache +schan_intr_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=3000000 diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/custom_led.bin b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/custom_led.bin new file mode 100755 index 0000000000000000000000000000000000000000..fb33257fbbe9d075892a096e3c581c6710df296c GIT binary patch literal 308 zcmV-40n7gIwO>Y7MomUUM)0%^95hS>BLgB2A&5o-Cb32VC%Q&494SDIMnz~^Qzdu- zJ*~2?00(IHTZd?WUAsmyLIcnh9AQQPDHYKb9DpY`LJ`nKMp;G;Kn5)b&;r;6Ee6pC z;0G-Q&D&pBZypTqjMxsWmM)1AlH~;`09v>hfA|oUvCMPH{GBY$aHa9pqIy*cG z3JVMk4i69!5)%|XK0iP~LPJDFMn^~i0s{mU78e)=1_uZk8XFubDl054E-x@iN=r;l GPESx?i&_={ literal 0 HcmV?d00001 diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/hwsku.json b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/hwsku.json new file mode 100644 index 0000000000..a559890f3a --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/hwsku.json @@ -0,0 +1,284 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet1": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet2": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet3": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet4": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet5": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet6": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet7": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet9": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet10": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet11": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet12": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet13": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet14": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet15": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet17": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet18": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet19": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet20": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet21": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet22": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet23": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet25": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet26": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet27": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet28": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet29": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet30": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet31": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet33": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet34": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet35": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet36": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet37": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet38": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet39": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet41": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet42": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet43": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet44": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet45": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet46": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet47": { + "default_brkout_mode": "1x25G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + } + } +} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/platform.json b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/platform.json new file mode 100644 index 0000000000..b303755d59 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/platform.json @@ -0,0 +1,396 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1", + "lanes": "29", + "breakout_modes": { + "1x25G": ["Eth1/1"] + } + }, + "Ethernet1": { + "index": "2", + "lanes": "30", + "breakout_modes": { + "1x25G": ["Eth2/1"] + } + }, + "Ethernet2": { + "index": "3", + "lanes": "31", + "breakout_modes": { + "1x25G": ["Eth3/1"] + } + }, + "Ethernet3": { + "index": "4", + "lanes": "32", + "breakout_modes": { + "1x25G": ["Eth4/1"] + } + }, + "Ethernet4": { + "index": "5", + "lanes": "33", + "breakout_modes": { + "1x25G": ["Eth5/1"] + } + }, + "Ethernet5": { + "index": "6", + "lanes": "34", + "breakout_modes": { + "1x25G": ["Eth6/1"] + } + }, + "Ethernet6": { + "index": "7", + "lanes": "35", + "breakout_modes": { + "1x25G": ["Eth7/1"] + } + }, + "Ethernet7": { + "index": "8", + "lanes": "36", + "breakout_modes": { + "1x25G": ["Eth8/1"] + } + }, + "Ethernet8": { + "index": "9", + "lanes": "37", + "breakout_modes": { + "1x25G": ["Eth9/1"] + } + }, + "Ethernet9": { + "index": "10", + "lanes": "38", + "breakout_modes": { + "1x25G": ["Eth10/1"] + } + }, + "Ethernet10": { + "index": "11", + "lanes": "39", + "breakout_modes": { + "1x25G": ["Eth11/1"] + } + }, + "Ethernet11": { + "index": "12", + "lanes": "40", + "breakout_modes": { + "1x25G": ["Eth12/1"] + } + }, + "Ethernet12": { + "index": "13", + "lanes": "49", + "breakout_modes": { + "1x25G": ["Eth13/1"] + } + }, + "Ethernet13": { + "index": "14", + "lanes": "50", + "breakout_modes": { + "1x25G": ["Eth14/1"] + } + }, + "Ethernet14": { + "index": "15", + "lanes": "51", + "breakout_modes": { + "1x25G": ["Eth15/1"] + } + }, + "Ethernet15": { + "index": "16", + "lanes": "52", + "breakout_modes": { + "1x25G": ["Eth16/1"] + } + }, + "Ethernet16": { + "index": "17", + "lanes": "53", + "breakout_modes": { + "1x25G": ["Eth17/1"] + } + }, + "Ethernet17": { + "index": "18", + "lanes": "54", + "breakout_modes": { + "1x25G": ["Eth18/1"] + } + }, + "Ethernet18": { + "index": "19", + "lanes": "55", + "breakout_modes": { + "1x25G": ["Eth19/1"] + } + }, + "Ethernet19": { + "index": "20", + "lanes": "56", + "breakout_modes": { + "1x25G": ["Eth20/1"] + } + }, + "Ethernet20": { + "index": "21", + "lanes": "57", + "breakout_modes": { + "1x25G": ["Eth21/1"] + } + }, + "Ethernet21": { + "index": "22", + "lanes": "58", + "breakout_modes": { + "1x25G": ["Eth22/1"] + } + }, + "Ethernet22": { + "index": "23", + "lanes": "59", + "breakout_modes": { + "1x25G": ["Eth23/1"] + } + }, + "Ethernet23": { + "index": "24", + "lanes": "60", + "breakout_modes": { + "1x25G": ["Eth24/1"] + } + }, + "Ethernet24": { + "index": "25", + "lanes": "9", + "breakout_modes": { + "1x25G": ["Eth25/1"] + } + }, + "Ethernet25": { + "index": "26", + "lanes": "10", + "breakout_modes": { + "1x25G": ["Eth26/1"] + } + }, + "Ethernet26": { + "index": "27", + "lanes": "11", + "breakout_modes": { + "1x25G": ["Eth27/1"] + } + }, + "Ethernet27": { + "index": "28", + "lanes": "12", + "breakout_modes": { + "1x25G": ["Eth28/1"] + } + }, + "Ethernet28": { + "index": "29", + "lanes": "13", + "breakout_modes": { + "1x25G": ["Eth29/1"] + } + }, + "Ethernet29": { + "index": "30", + "lanes": "14", + "breakout_modes": { + "1x25G": ["Eth30/1"] + } + }, + "Ethernet30": { + "index": "31", + "lanes": "15", + "breakout_modes": { + "1x25G": ["Eth31/1"] + } + }, + "Ethernet31": { + "index": "32", + "lanes": "16", + "breakout_modes": { + "1x25G": ["Eth32/1"] + } + }, + "Ethernet32": { + "index": "33", + "lanes": "17", + "breakout_modes": { + "1x25G": ["Eth33/1"] + } + }, + "Ethernet33": { + "index": "34", + "lanes": "18", + "breakout_modes": { + "1x25G": ["Eth34/1"] + } + }, + "Ethernet34": { + "index": "35", + "lanes": "19", + "breakout_modes": { + "1x25G": ["Eth35/1"] + } + }, + "Ethernet35": { + "index": "36", + "lanes": "20", + "breakout_modes": { + "1x25G": ["Eth36/1"] + } + }, + "Ethernet36": { + "index": "37", + "lanes": "61", + "breakout_modes": { + "1x25G": ["Eth37/1"] + } + }, + "Ethernet37": { + "index": "38", + "lanes": "62", + "breakout_modes": { + "1x25G": ["Eth38/1"] + } + }, + "Ethernet38": { + "index": "39", + "lanes": "63", + "breakout_modes": { + "1x25G": ["Eth39/1"] + } + }, + "Ethernet39": { + "index": "40", + "lanes": "64", + "breakout_modes": { + "1x25G": ["Eth40/1"] + } + }, + "Ethernet40": { + "index": "41", + "lanes": "65", + "breakout_modes": { + "1x25G": ["Eth41/1"] + } + }, + "Ethernet41": { + "index": "42", + "lanes": "66", + "breakout_modes": { + "1x25G": ["Eth42/1"] + } + }, + "Ethernet42": { + "index": "43", + "lanes": "67", + "breakout_modes": { + "1x25G": ["Eth43/1"] + } + }, + "Ethernet43": { + "index": "44", + "lanes": "68", + "breakout_modes": { + "1x25G": ["Eth44/1"] + } + }, + "Ethernet44": { + "index": "45", + "lanes": "69", + "breakout_modes": { + "1x25G": ["Eth45/1"] + } + }, + "Ethernet45": { + "index": "46", + "lanes": "70", + "breakout_modes": { + "1x25G": ["Eth46/1"] + } + }, + "Ethernet46": { + "index": "47", + "lanes": "71", + "breakout_modes": { + "1x25G": ["Eth47/1"] + } + }, + "Ethernet47": { + "index": "48", + "lanes": "72", + "breakout_modes": { + "1x25G": ["Eth48/1"] + } + }, + "Ethernet48": { + "index": "49,49,49,49", + "lanes": "41,42,43,44", + "breakout_modes": { + "1x100G": ["Eth49/1"] + } + }, + "Ethernet52": { + "index": "50,50,50,50", + "lanes": "45,46,47,48", + "breakout_modes": { + "1x100G": ["Eth50/1"] + } + }, + "Ethernet56": { + "index": "51,51,51,51", + "lanes": "73,74,75,76", + "breakout_modes": { + "1x100G": ["Eth51/1"] + } + }, + "Ethernet60": { + "index": "52,52,52,52", + "lanes": "77,78,79,80", + "breakout_modes": { + "1x100G": ["Eth52/1"] + } + }, + "Ethernet64": { + "index": "53,53,53,53", + "lanes": "1,2,3,4", + "breakout_modes": { + "1x100G": ["Eth53/1"] + } + }, + "Ethernet68": { + "index": "54,54,54,54", + "lanes": "21,22,23,24", + "breakout_modes": { + "1x100G": ["Eth54/1"] + } + }, + "Ethernet72": { + "index": "55,55,55,55", + "lanes": "5,6,7,8", + "breakout_modes": { + "1x100G": ["Eth55/1"] + } + }, + "Ethernet76": { + "index": "56,56,56,56", + "lanes": "25,26,27,28", + "breakout_modes": { + "1x100G": ["Eth56/1"] + } + } + } +} diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/platform_components.json b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/platform_components.json new file mode 100644 index 0000000000..165eacad2d --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/platform_components.json @@ -0,0 +1,17 @@ +{ + "chassis": { + "Questone_2A": { + "component": { + "BIOS": {}, + "ONIE": {}, + "BMC": {}, + "FPGA": {}, + "CPLD COMe": {}, + "CPLD BASE": {}, + "CPLD SW1": {}, + "CPLD SW2": {}, + "SSD": {} + } + } + } +} diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/port_config.ini b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/port_config.ini new file mode 100644 index 0000000000..37d2d92652 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/port_config.ini @@ -0,0 +1,57 @@ +# name lanes alias index speed mtu admin_status fec +Ethernet0 29 Eth1/1 1 25000 9216 up rs +Ethernet1 30 Eth2/1 2 25000 9216 up rs +Ethernet2 31 Eth3/1 3 25000 9216 up rs +Ethernet3 32 Eth4/1 4 25000 9216 up rs +Ethernet4 33 Eth5/1 5 25000 9216 up rs +Ethernet5 34 Eth6/1 6 25000 9216 up rs +Ethernet6 35 Eth7/1 7 25000 9216 up rs +Ethernet7 36 Eth8/1 8 25000 9216 up rs +Ethernet8 37 Eth9/1 9 25000 9216 up rs +Ethernet9 38 Eth10/1 10 25000 9216 up rs +Ethernet10 39 Eth11/1 11 25000 9216 up rs +Ethernet11 40 Eth12/1 12 25000 9216 up rs +Ethernet12 49 Eth13/1 13 25000 9216 up rs +Ethernet13 50 Eth14/1 14 25000 9216 up rs +Ethernet14 51 Eth15/1 15 25000 9216 up rs +Ethernet15 52 Eth16/1 16 25000 9216 up rs +Ethernet16 53 Eth17/1 17 25000 9216 up rs +Ethernet17 54 Eth18/1 18 25000 9216 up rs +Ethernet18 55 Eth19/1 19 25000 9216 up rs +Ethernet19 56 Eth20/1 20 25000 9216 up rs +Ethernet20 57 Eth21/1 21 25000 9216 up rs +Ethernet21 58 Eth22/1 22 25000 9216 up rs +Ethernet22 59 Eth23/1 23 25000 9216 up rs +Ethernet23 60 Eth24/1 24 25000 9216 up rs +Ethernet24 9 Eth25/1 25 25000 9216 up rs +Ethernet25 10 Eth26/1 26 25000 9216 up rs +Ethernet26 11 Eth27/1 27 25000 9216 up rs +Ethernet27 12 Eth28/1 28 25000 9216 up rs +Ethernet28 13 Eth29/1 29 25000 9216 up rs +Ethernet29 14 Eth30/1 30 25000 9216 up rs +Ethernet30 15 Eth31/1 31 25000 9216 up rs +Ethernet31 16 Eth32/1 32 25000 9216 up rs +Ethernet32 17 Eth33/1 33 25000 9216 up rs +Ethernet33 18 Eth34/1 34 25000 9216 up rs +Ethernet34 19 Eth35/1 35 25000 9216 up rs +Ethernet35 20 Eth36/1 36 25000 9216 up rs +Ethernet36 61 Eth37/1 37 25000 9216 up rs +Ethernet37 62 Eth38/1 38 25000 9216 up rs +Ethernet38 63 Eth39/1 39 25000 9216 up rs +Ethernet39 64 Eth40/1 40 25000 9216 up rs +Ethernet40 65 Eth41/1 41 25000 9216 up rs +Ethernet41 66 Eth42/1 42 25000 9216 up rs +Ethernet42 67 Eth43/1 43 25000 9216 up rs +Ethernet43 68 Eth44/1 44 25000 9216 up rs +Ethernet44 69 Eth45/1 45 25000 9216 up rs +Ethernet45 70 Eth46/1 46 25000 9216 up rs +Ethernet46 71 Eth47/1 47 25000 9216 up rs +Ethernet47 72 Eth48/1 48 25000 9216 up rs +Ethernet48 41,42,43,44 Eth49/1 49 100000 9216 up rs +Ethernet52 45,46,47,48 Eth50/1 50 100000 9216 up rs +Ethernet56 73,74,75,76 Eth51/1 51 100000 9216 up rs +Ethernet60 77,78,79,80 Eth52/1 52 100000 9216 up rs +Ethernet64 1,2,3,4 Eth53/1 53 100000 9216 up rs +Ethernet68 21,22,23,24 Eth54/1 54 100000 9216 up rs +Ethernet72 5,6,7,8 Eth55/1 55 100000 9216 up rs +Ethernet76 25,26,27,28 Eth56/1 56 100000 9216 up rs diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/sai.profile.j2 b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/sai.profile.j2 new file mode 100644 index 0000000000..62a1db9e09 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/sai.profile.j2 @@ -0,0 +1,16 @@ +{# Get sai.profile based on vxlan_profile. Vxlan's config.bcm file is the default one #} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as13-48f8h-vxlan.config.bcm' -%} +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined -%} +{%- if DEVICE_METADATA['localhost']['vxlan_profile'] is defined -%} +{%- set vxlan_profile = DEVICE_METADATA['localhost']['vxlan_profile'] -%} +{%- if 'enable' in vxlan_profile.lower() %} +{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as13-48f8h-vxlan.config.bcm' -%} +{%- else %} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as13-48f8h.config.bcm' -%} +{%- endif %} +{%- else %} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-as13-48f8h-vxlan.config.bcm' -%} +{%- endif %} +{%- endif %} +{# Write the contents of sai_profile_filename to sai.profile file #} +{{ sai_profile_contents }} diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/td3-as13-48f8h-vxlan.config.bcm b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/td3-as13-48f8h-vxlan.config.bcm new file mode 100755 index 0000000000..7d444dfb53 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/td3-as13-48f8h-vxlan.config.bcm @@ -0,0 +1,423 @@ +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 +oversubscribe_mode=1 +pbmp_xport_xe=0x11ffffffe1ffffffe +stable_size=0x5500000 +ifp_inports_support_enable=1 + +#FC0 +portmap_1.0=1:100 + +#FC1 +portmap_2.0=5:100 + +#FC2 +portmap_3.0=9:25 +portmap_4.0=10:25 +portmap_5.0=11:25 +portmap_6.0=12:25 + +#FC3 +portmap_7.0=13:25 +portmap_8.0=14:25 +portmap_9.0=15:25 +portmap_10.0=16:25 + +#FC4 +portmap_11.0=17:25 +portmap_12.0=18:25 +portmap_13.0=19:25 +portmap_14.0=20:25 + +#FC5 +portmap_15.0=21:100 + +#FC6 +portmap_16.0=25:100 + +#FC7 +portmap_17.0=29:25 +portmap_18.0=30:25 +portmap_19.0=31:25 +portmap_20.0=32:25 + +#FC8 +portmap_21.0=33:25 +portmap_22.0=34:25 +portmap_23.0=35:25 +portmap_24.0=36:25 + +#FC9 +portmap_25.0=37:25 +portmap_26.0=38:25 +portmap_27.0=39:25 +portmap_28.0=40:25 + +#FC10 +portmap_33.0=41:100 + +#FC11 +portmap_34.0=45:100 + +#FC12 +portmap_35.0=49:25 +portmap_36.0=50:25 +portmap_37.0=51:25 +portmap_38.0=52:25 + +#FC13 +portmap_39.0=53:25 +portmap_40.0=54:25 +portmap_41.0=55:25 +portmap_42.0=56:25 + +#FC14 +portmap_43.0=57:25 +portmap_44.0=58:25 +portmap_45.0=59:25 +portmap_46.0=60:25 + +#FC15 +portmap_47.0=61:25 +portmap_48.0=62:25 +portmap_49.0=63:25 +portmap_50.0=64:25 + +#FC16 +portmap_51.0=65:25 +portmap_52.0=66:25 +portmap_53.0=67:25 +portmap_54.0=68:25 + +#FC17 +portmap_55.0=69:25 +portmap_56.0=70:25 +portmap_57.0=71:25 +portmap_58.0=72:25 + +#FC18 +portmap_59.0=73:100 + +#FC19 +portmap_60.0=77:100 + + +#portmap_64.0=81:10 + +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1302 +phy_chain_tx_lane_map_physical{9.0}=0x0123 +phy_chain_rx_lane_map_physical{9.0}=0x1032 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x1032 +phy_chain_tx_lane_map_physical{21.0}=0x1302 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_tx_lane_map_physical{25.0}=0x3120 +phy_chain_rx_lane_map_physical{25.0}=0x1032 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x0123 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{37.0}=0x0123 +phy_chain_rx_lane_map_physical{37.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x1302 +phy_chain_rx_lane_map_physical{41.0}=0x1023 +phy_chain_tx_lane_map_physical{45.0}=0x1032 +phy_chain_rx_lane_map_physical{45.0}=0x0213 +phy_chain_tx_lane_map_physical{49.0}=0x3210 +phy_chain_rx_lane_map_physical{49.0}=0x2301 +phy_chain_tx_lane_map_physical{53.0}=0x3210 +phy_chain_rx_lane_map_physical{53.0}=0x2301 +phy_chain_tx_lane_map_physical{57.0}=0x3210 +phy_chain_rx_lane_map_physical{57.0}=0x2301 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x2301 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x2301 +phy_chain_tx_lane_map_physical{69.0}=0x3210 +phy_chain_rx_lane_map_physical{69.0}=0x2301 +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_tx_lane_map_physical{77.0}=0x0132 +phy_chain_rx_lane_map_physical{77.0}=0x3012 +phy_chain_tx_lane_map_physical{81.0}=0x3210 +phy_chain_rx_lane_map_physical{81.0}=0x3201 + +#FC0 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +#FC1 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 + +#FC2 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 + +#FC3 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 + +#FC4 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x1 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 + +#FC5 +phy_chain_tx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 + +#FC6 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x0 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 + +#FC7 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x1 + +#FC8 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 + +#FC9 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 + +#FC10 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 + +#FC11 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +#FC12 +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 + +#FC13 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 + +#FC14 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x1 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 + +#FC15 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 + +#FC16 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 + +#FC17 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 + +#FC18 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x0 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +#FC19 +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 + + +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 + + +dport_map_port_17=1 +dport_map_port_18=2 +dport_map_port_19=3 +dport_map_port_20=4 +dport_map_port_21=5 +dport_map_port_22=6 +dport_map_port_23=7 +dport_map_port_24=8 +dport_map_port_25=9 +dport_map_port_26=10 +dport_map_port_27=11 +dport_map_port_28=12 +dport_map_port_35=13 +dport_map_port_36=14 +dport_map_port_37=15 +dport_map_port_38=16 +dport_map_port_39=17 +dport_map_port_40=18 +dport_map_port_41=19 +dport_map_port_42=20 +dport_map_port_43=21 +dport_map_port_44=22 +dport_map_port_45=23 +dport_map_port_46=24 +dport_map_port_3=25 +dport_map_port_4=26 +dport_map_port_5=27 +dport_map_port_6=28 +dport_map_port_7=29 +dport_map_port_8=30 +dport_map_port_9=31 +dport_map_port_10=32 +dport_map_port_11=33 +dport_map_port_12=34 +dport_map_port_13=35 +dport_map_port_14=36 +dport_map_port_47=37 +dport_map_port_48=38 +dport_map_port_49=39 +dport_map_port_50=40 +dport_map_port_51=41 +dport_map_port_52=42 +dport_map_port_53=43 +dport_map_port_54=44 +dport_map_port_55=45 +dport_map_port_56=46 +dport_map_port_57=47 +dport_map_port_58=48 +dport_map_port_33=49 +dport_map_port_34=50 +dport_map_port_59=51 +dport_map_port_60=52 +dport_map_port_1=53 +dport_map_port_15=54 +dport_map_port_2=55 +dport_map_port_16=56 +#dport_map_port_64=57 + +#VxLAN +sai_tunnel_support=1 +use_all_splithorizon_groups=1 +bcm_tunnel_term_compatible_mode=1 +flow_init_mode=1 +l3_ecmp_levels=2 +riot_enable=1 +riot_overlay_l3_intf_mem_size=8192 +riot_overlay_l3_egress_mem_size=32768 +riot_overlay_ecmp_resilient_hash_size=16384 diff --git a/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/td3-as13-48f8h.config.bcm b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/td3-as13-48f8h.config.bcm new file mode 100755 index 0000000000..303b92dd39 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/Questone_2A/td3-as13-48f8h.config.bcm @@ -0,0 +1,412 @@ +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 +oversubscribe_mode=1 +pbmp_xport_xe=0x11ffffffe1ffffffe +stable_size=0x5500000 +ifp_inports_support_enable=1 + +#FC0 +portmap_1.0=1:100 + +#FC1 +portmap_2.0=5:100 + +#FC2 +portmap_3.0=9:25 +portmap_4.0=10:25 +portmap_5.0=11:25 +portmap_6.0=12:25 + +#FC3 +portmap_7.0=13:25 +portmap_8.0=14:25 +portmap_9.0=15:25 +portmap_10.0=16:25 + +#FC4 +portmap_11.0=17:25 +portmap_12.0=18:25 +portmap_13.0=19:25 +portmap_14.0=20:25 + +#FC5 +portmap_15.0=21:100 + +#FC6 +portmap_16.0=25:100 + +#FC7 +portmap_17.0=29:25 +portmap_18.0=30:25 +portmap_19.0=31:25 +portmap_20.0=32:25 + +#FC8 +portmap_21.0=33:25 +portmap_22.0=34:25 +portmap_23.0=35:25 +portmap_24.0=36:25 + +#FC9 +portmap_25.0=37:25 +portmap_26.0=38:25 +portmap_27.0=39:25 +portmap_28.0=40:25 + +#FC10 +portmap_33.0=41:100 + +#FC11 +portmap_34.0=45:100 + +#FC12 +portmap_35.0=49:25 +portmap_36.0=50:25 +portmap_37.0=51:25 +portmap_38.0=52:25 + +#FC13 +portmap_39.0=53:25 +portmap_40.0=54:25 +portmap_41.0=55:25 +portmap_42.0=56:25 + +#FC14 +portmap_43.0=57:25 +portmap_44.0=58:25 +portmap_45.0=59:25 +portmap_46.0=60:25 + +#FC15 +portmap_47.0=61:25 +portmap_48.0=62:25 +portmap_49.0=63:25 +portmap_50.0=64:25 + +#FC16 +portmap_51.0=65:25 +portmap_52.0=66:25 +portmap_53.0=67:25 +portmap_54.0=68:25 + +#FC17 +portmap_55.0=69:25 +portmap_56.0=70:25 +portmap_57.0=71:25 +portmap_58.0=72:25 + +#FC18 +portmap_59.0=73:100 + +#FC19 +portmap_60.0=77:100 + + +#portmap_64.0=81:10 + +phy_chain_tx_lane_map_physical{1.0}=0x0123 +phy_chain_rx_lane_map_physical{1.0}=0x1302 +phy_chain_tx_lane_map_physical{5.0}=0x1032 +phy_chain_rx_lane_map_physical{5.0}=0x1302 +phy_chain_tx_lane_map_physical{9.0}=0x0123 +phy_chain_rx_lane_map_physical{9.0}=0x1032 +phy_chain_tx_lane_map_physical{13.0}=0x0123 +phy_chain_rx_lane_map_physical{13.0}=0x1032 +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x1032 +phy_chain_tx_lane_map_physical{21.0}=0x1302 +phy_chain_rx_lane_map_physical{21.0}=0x1032 +phy_chain_tx_lane_map_physical{25.0}=0x3120 +phy_chain_rx_lane_map_physical{25.0}=0x1032 +phy_chain_tx_lane_map_physical{29.0}=0x0123 +phy_chain_rx_lane_map_physical{29.0}=0x1032 +phy_chain_tx_lane_map_physical{33.0}=0x0123 +phy_chain_rx_lane_map_physical{33.0}=0x1032 +phy_chain_tx_lane_map_physical{37.0}=0x0123 +phy_chain_rx_lane_map_physical{37.0}=0x1032 +phy_chain_tx_lane_map_physical{41.0}=0x1302 +phy_chain_rx_lane_map_physical{41.0}=0x1023 +phy_chain_tx_lane_map_physical{45.0}=0x1032 +phy_chain_rx_lane_map_physical{45.0}=0x0213 +phy_chain_tx_lane_map_physical{49.0}=0x3210 +phy_chain_rx_lane_map_physical{49.0}=0x2301 +phy_chain_tx_lane_map_physical{53.0}=0x3210 +phy_chain_rx_lane_map_physical{53.0}=0x2301 +phy_chain_tx_lane_map_physical{57.0}=0x3210 +phy_chain_rx_lane_map_physical{57.0}=0x2301 +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x2301 +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x2301 +phy_chain_tx_lane_map_physical{69.0}=0x3210 +phy_chain_rx_lane_map_physical{69.0}=0x2301 +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x2031 +phy_chain_tx_lane_map_physical{77.0}=0x0132 +phy_chain_rx_lane_map_physical{77.0}=0x3012 +phy_chain_tx_lane_map_physical{81.0}=0x3210 +phy_chain_rx_lane_map_physical{81.0}=0x3201 + +#FC0 +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x1 +phy_chain_rx_polarity_flip_physical{3.0}=0x1 +phy_chain_tx_polarity_flip_physical{4.0}=0x0 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +#FC1 +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x1 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x0 +phy_chain_tx_polarity_flip_physical{7.0}=0x1 +phy_chain_rx_polarity_flip_physical{7.0}=0x0 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x0 + +#FC2 +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x1 +phy_chain_tx_polarity_flip_physical{10.0}=0x1 +phy_chain_rx_polarity_flip_physical{10.0}=0x0 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x1 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x0 + +#FC3 +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x1 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x0 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x1 +phy_chain_rx_polarity_flip_physical{16.0}=0x0 + +#FC4 +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x1 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x1 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x0 + +#FC5 +phy_chain_tx_polarity_flip_physical{21.0}=0x1 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x1 +phy_chain_rx_polarity_flip_physical{23.0}=0x0 +phy_chain_tx_polarity_flip_physical{24.0}=0x0 +phy_chain_rx_polarity_flip_physical{24.0}=0x0 + +#FC6 +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x0 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x1 +phy_chain_tx_polarity_flip_physical{27.0}=0x1 +phy_chain_rx_polarity_flip_physical{27.0}=0x0 +phy_chain_tx_polarity_flip_physical{28.0}=0x0 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 + +#FC7 +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x0 +phy_chain_tx_polarity_flip_physical{30.0}=0x0 +phy_chain_rx_polarity_flip_physical{30.0}=0x1 +phy_chain_tx_polarity_flip_physical{31.0}=0x1 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x1 + +#FC8 +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x0 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x1 +phy_chain_tx_polarity_flip_physical{35.0}=0x1 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x0 +phy_chain_rx_polarity_flip_physical{36.0}=0x1 + +#FC9 +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x0 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x1 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x0 + +#FC10 +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x0 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x0 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x0 + +#FC11 +phy_chain_tx_polarity_flip_physical{45.0}=0x0 +phy_chain_rx_polarity_flip_physical{45.0}=0x1 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x0 +phy_chain_rx_polarity_flip_physical{47.0}=0x0 +phy_chain_tx_polarity_flip_physical{48.0}=0x1 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +#FC12 +phy_chain_tx_polarity_flip_physical{49.0}=0x0 +phy_chain_rx_polarity_flip_physical{49.0}=0x1 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x0 + +#FC13 +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x1 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x0 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x0 + +#FC14 +phy_chain_tx_polarity_flip_physical{57.0}=0x0 +phy_chain_rx_polarity_flip_physical{57.0}=0x1 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x0 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x1 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x0 + +#FC15 +phy_chain_tx_polarity_flip_physical{61.0}=0x1 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x0 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x1 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 + +#FC16 +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x1 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x0 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x1 + +#FC17 +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x0 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x1 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x1 + +#FC18 +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x0 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +#FC19 +phy_chain_tx_polarity_flip_physical{77.0}=0x1 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x1 +phy_chain_rx_polarity_flip_physical{78.0}=0x1 +phy_chain_tx_polarity_flip_physical{79.0}=0x0 +phy_chain_rx_polarity_flip_physical{79.0}=0x0 +phy_chain_tx_polarity_flip_physical{80.0}=0x0 +phy_chain_rx_polarity_flip_physical{80.0}=0x0 + + +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x1 + + +dport_map_port_17=1 +dport_map_port_18=2 +dport_map_port_19=3 +dport_map_port_20=4 +dport_map_port_21=5 +dport_map_port_22=6 +dport_map_port_23=7 +dport_map_port_24=8 +dport_map_port_25=9 +dport_map_port_26=10 +dport_map_port_27=11 +dport_map_port_28=12 +dport_map_port_35=13 +dport_map_port_36=14 +dport_map_port_37=15 +dport_map_port_38=16 +dport_map_port_39=17 +dport_map_port_40=18 +dport_map_port_41=19 +dport_map_port_42=20 +dport_map_port_43=21 +dport_map_port_44=22 +dport_map_port_45=23 +dport_map_port_46=24 +dport_map_port_3=25 +dport_map_port_4=26 +dport_map_port_5=27 +dport_map_port_6=28 +dport_map_port_7=29 +dport_map_port_8=30 +dport_map_port_9=31 +dport_map_port_10=32 +dport_map_port_11=33 +dport_map_port_12=34 +dport_map_port_13=35 +dport_map_port_14=36 +dport_map_port_47=37 +dport_map_port_48=38 +dport_map_port_49=39 +dport_map_port_50=40 +dport_map_port_51=41 +dport_map_port_52=42 +dport_map_port_53=43 +dport_map_port_54=44 +dport_map_port_55=45 +dport_map_port_56=46 +dport_map_port_57=47 +dport_map_port_58=48 +dport_map_port_33=49 +dport_map_port_34=50 +dport_map_port_59=51 +dport_map_port_60=52 +dport_map_port_1=53 +dport_map_port_15=54 +dport_map_port_2=55 +dport_map_port_16=56 +#dport_map_port_64=57 diff --git a/device/celestica/x86_64-cel_questone_2-r0/installer.conf b/device/celestica/x86_64-cel_questone_2-r0/installer.conf new file mode 100644 index 0000000000..48126f4354 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/installer.conf @@ -0,0 +1,4 @@ +CONSOLE_PORT=0xe060 +CONSOLE_DEV=0 +CONSOLE_SPEED=115200 +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="processor.max_cstate=1 intel_idle.max_cstate=0 intel_iommu=off thermal.off=1 noirqdebug" diff --git a/device/celestica/x86_64-cel_questone_2-r0/led_proc_init.soc b/device/celestica/x86_64-cel_questone_2-r0/led_proc_init.soc new file mode 100644 index 0000000000..6f242fa07d --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/led_proc_init.soc @@ -0,0 +1,8 @@ +#Enable all ports +#port all en=1 +#sleep 6 +#linkscan 250000; port xe,ce linkscan=on + +#Load LED +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin +led auto on; led start diff --git a/device/celestica/x86_64-cel_questone_2-r0/opennsl-postinit.cfg b/device/celestica/x86_64-cel_questone_2-r0/opennsl-postinit.cfg new file mode 100644 index 0000000000..7008c14c0f --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/opennsl-postinit.cfg @@ -0,0 +1,3 @@ +linkscan 250000; port xe,ce linkscan=on +sleep 1 +led auto on; led start diff --git a/device/celestica/x86_64-cel_questone_2-r0/pcie.yaml b/device/celestica/x86_64-cel_questone_2-r0/pcie.yaml new file mode 100644 index 0000000000..bafe4a0d6d --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/pcie.yaml @@ -0,0 +1,153 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1980' + name: 'Host bridge: Intel Corporation Atom Processor C3000 Series System Agent (rev + 11)' +- bus: '00' + dev: '04' + fn: '0' + id: 19a1 + name: 'Host bridge: Intel Corporation Atom Processor C3000 Series Error Registers + (rev 11)' +- bus: '00' + dev: '05' + fn: '0' + id: 19a2 + name: 'Generic system peripheral [0807]: Intel Corporation Atom Processor C3000 + Series Root Complex Event Collector (rev 11)' +- bus: '00' + dev: '06' + fn: '0' + id: 19a3 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated QAT + Root Port (rev 11)' +- bus: '00' + dev: 09 + fn: '0' + id: 19a4 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #0 (rev 11)' +- bus: '00' + dev: '10' + fn: '0' + id: 19aa + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #6 (rev 11)' +- bus: '00' + dev: '11' + fn: '0' + id: 19ab + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #7 (rev 11)' +- bus: '00' + dev: '12' + fn: '0' + id: 19ac + name: 'System peripheral: Intel Corporation Atom Processor C3000 Series SMBus Contoller + - Host (rev 11)' +- bus: '00' + dev: '14' + fn: '0' + id: 19c2 + name: 'SATA controller: Intel Corporation Atom Processor C3000 Series SATA Controller + 1 (rev 11)' +- bus: '00' + dev: '15' + fn: '0' + id: 19d0 + name: 'USB controller: Intel Corporation Atom Processor C3000 Series USB 3.0 xHCI + Controller (rev 11)' +- bus: '00' + dev: '16' + fn: '0' + id: 19d1 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated LAN + Root Port #0 (rev 11)' +- bus: '00' + dev: '18' + fn: '0' + id: 19d3 + name: 'Communication controller: Intel Corporation Atom Processor C3000 Series ME + HECI 1 (rev 11)' +- bus: '00' + dev: 1a + fn: '0' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1a + fn: '1' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1a + fn: '2' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1c + fn: '0' + id: 19db + name: 'SD Host controller: Intel Corporation Device 19db (rev 11)' +- bus: '00' + dev: 1f + fn: '0' + id: 19dc + name: 'ISA bridge: Intel Corporation Atom Processor C3000 Series LPC or eSPI (rev + 11)' +- bus: '00' + dev: 1f + fn: '2' + id: 19de + name: 'Memory controller: Intel Corporation Atom Processor C3000 Series Power Management + Controller (rev 11)' +- bus: '00' + dev: 1f + fn: '4' + id: 19df + name: 'SMBus: Intel Corporation Atom Processor C3000 Series SMBus controller (rev + 11)' +- bus: '00' + dev: 1f + fn: '5' + id: 19e0 + name: 'Serial bus controller [0c80]: Intel Corporation Atom Processor C3000 Series + SPI Controller (rev 11)' +- bus: '01' + dev: '00' + fn: '0' + id: 19e2 + name: 'Co-processor: Intel Corporation Atom Processor C3000 Series QuickAssist Technology + (rev 11)' +- bus: '02' + dev: '00' + fn: '0' + id: b770 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b770 (rev 01)' +- bus: '03' + dev: '00' + fn: '0' + id: '7021' + name: 'Memory controller: Xilinx Corporation Device 7021' +- bus: '04' + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: '05' + dev: '00' + fn: '0' + id: 15c2 + name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane + (rev 11)' +- bus: '05' + dev: '00' + fn: '1' + id: 15c2 + name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane + (rev 11)' diff --git a/device/celestica/x86_64-cel_questone_2-r0/platform_asic b/device/celestica/x86_64-cel_questone_2-r0/platform_asic new file mode 100644 index 0000000000..9604676527 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/platform_asic @@ -0,0 +1 @@ +broadcom diff --git a/device/celestica/x86_64-cel_questone_2-r0/platform_reboot b/device/celestica/x86_64-cel_questone_2-r0/platform_reboot new file mode 100755 index 0000000000..12a18efe1d --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/platform_reboot @@ -0,0 +1,6 @@ +#!/bin/bash + +# Set all LEDs to BMC's control +ipmitool raw 0x3a 0x0f 0x02 0x01 &> /dev/null + +/usr/local/bin/questone2_platform_shutdown.sh system diff --git a/device/celestica/x86_64-cel_questone_2-r0/plugins/eeprom.py b/device/celestica/x86_64-cel_questone_2-r0/plugins/eeprom.py new file mode 100644 index 0000000000..2289553982 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/plugins/eeprom.py @@ -0,0 +1,23 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica DX010 +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + from sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class board(eeprom_tlvinfo.TlvInfoDecoder): + + def __init__(self, name, path, cpld_root, ro): + self.eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" + super(board, self).__init__(self.eeprom_path, 0, '', True) + diff --git a/device/celestica/x86_64-cel_questone_2-r0/plugins/sfputil.py b/device/celestica/x86_64-cel_questone_2-r0/plugins/sfputil.py new file mode 100755 index 0000000000..03882c65ac --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/plugins/sfputil.py @@ -0,0 +1,312 @@ +#!/usr/bin/env python +# +# Platform-specific SFP transceiver interface for SONiC +# + +try: + import time + from sonic_sfp.sfputilbase import SfpUtilBase + import struct +except ImportError as e: + raise ImportError("%s - required module not found" % str(e)) + + +class SfpUtil(SfpUtilBase): + """Platform-specific SfpUtil class""" + + PORT_START = 0 + PORT_END = 55 + QSFP_PORT_START = 48 + QSFP_PORT_END = 55 + __xcvr_presence = {} + + EEPROM_OFFSET = 9 + PORT_INFO_PATH = '/sys/class/questone2_fpga' + + _port_name = "" + _port_to_eeprom_mapping = {} + _port_to_i2cbus_mapping = {} + + @property + def port_start(self): + return self.PORT_START + + @property + def port_end(self): + return self.PORT_END + + @property + def qsfp_ports(self): + return range(self.QSFP_PORT_START, self.QSFP_PORT_END + 1) + + @property + def port_to_eeprom_mapping(self): + return self._port_to_eeprom_mapping + + @property + def port_to_i2cbus_mapping(self): + return self._port_to_i2cbus_mapping + + def get_port_name(self, port_num): + if port_num in self.qsfp_ports: + self._port_name = "QSFP" + str(port_num - self.QSFP_PORT_START + 1) + else: + self._port_name = "SFP" + str(port_num + 1) + return self._port_name + + def get_eeprom_dom_raw(self, port_num): + if port_num in self.qsfp_ports: + # QSFP DOM EEPROM is also at addr 0x50 and thus also stored in eeprom_ifraw + return None + else: + # Read dom eeprom at addr 0x51 + return self._read_eeprom_devid(port_num, self.DOM_EEPROM_ADDR, 256) + + def __init__(self): + # Override port_to_eeprom_mapping for class initialization + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' + + for x in range(self.PORT_START, self.PORT_END+1): + # port_index = 0 , it's path = /sys/bus/i2c/devices/i2c-10/10-0050/eeprom + # port_index = 55, it's path = /sys/bus/i2c/devices/i2c-65/65-0050/eeprom + # so the real offset is 10 + self.port_to_i2cbus_mapping[x] = (x + 1 + self.EEPROM_OFFSET) + self.port_to_eeprom_mapping[x] = eeprom_path.format( + x + 1 + self.EEPROM_OFFSET) + SfpUtilBase.__init__(self) + for x in range(self.PORT_START, self.PORT_END+1): + self.__xcvr_presence[x] = self.get_presence(x) + + def _do_write_file(self, file_handle, offset, value): + file_handle.seek(offset) + file_handle.write(hex(value)) + file_handle.close() + + def get_presence(self, port_num): + + # Check for invalid port_num + if port_num not in range(self.port_start, self.port_end + 1): + return False + + # Get path for access port presence status + port_name = self.get_port_name(port_num) + sysfs_filename = "qsfp_modprs" if port_num in self.qsfp_ports else "sfp_modabs" + reg_path = "/".join([self.PORT_INFO_PATH, port_name, sysfs_filename]) + + # Read status + try: + reg_file = open(reg_path) + content = reg_file.readline().rstrip() + reg_value = int(content) + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Module present is active low + if reg_value == 0: + return True + + return False + + def get_low_power_mode(self, port_num): + if not self.get_presence(port_num): + return None + + eeprom_raw = [] + eeprom_raw.append("0x00") + + lpmode = False + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'.format(port_num + 1 + self.EEPROM_OFFSET) + if port_num >= 49: + try: + with open(eeprom_path, mode="rb", buffering=0) as eeprom: + eeprom.seek(93) + raw = eeprom.read(1) + eeprom.close() + except Exception as err: + return None + + if len(raw) == 0: + return None + eeprom_raw[0] = hex(ord(raw[0]))[2:].zfill(2) + + power_data = int(eeprom_raw[0], 16) + # if lpmod, power-override bit and power-set bit are both setted + # bit0 bit1 + lpmode = power_data & 0x03 != 0 + else: + return None + + return lpmode + + def set_low_power_mode(self, port_num, lpmode): + # Check for invalid QSFP port_num + if port_num not in self.qsfp_ports: + return False + + if not self.get_presence(port_num): + return False + eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'.format(port_num + 1 + self.EEPROM_OFFSET) + try: + reg_file = open(eeprom_path, mode="wb+") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(93) + power_raw = reg_file.read(1) + if power_raw is None: + return False + power_data = int(hex(ord(power_raw))[2:].zfill(2), 16) + + if lpmode: + power_data |= 0x03 + else: + power_data &= ~(0x03) + + reg_file.seek(93) + reg_file.write(struct.pack('B', int(power_data))) + reg_file.close() + + return True + + def reset(self, port_num): + # Check for invalid QSFP port_num + if port_num not in self.qsfp_ports: + return False + + try: + port_name = self.get_port_name(port_num) + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(0)) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "qsfp_reset"]), "w") + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + reg_file.seek(0) + reg_file.write(hex(1)) + reg_file.close() + + return True + + def get_transceiver_change_event(self, timeout=0): + """ + To detect if any transceiver change event happens. + """ + start_ms = time.time() * 1000 + xcvr_change_event_dict = {} + event = False + + while True: + time.sleep(0.5) + for port in range(self.port_start, self.port_end+1): + curr_presence = self.get_presence(port) + if curr_presence != self.__xcvr_presence[port]: + if curr_presence is True: + xcvr_change_event_dict[str(port)] = '1' + self.__xcvr_presence[port] = True + elif curr_presence is False: + xcvr_change_event_dict[str(port)] = '0' + self.__xcvr_presence[port] = False + event = True + + if event is True: + return True, xcvr_change_event_dict + + if timeout: + now_ms = time.time() * 1000 + if (now_ms - start_ms >= timeout): + return True, xcvr_change_event_dict + + def tx_disable(self, port_num, disable): + """ + @param port_num index of physical port + @param disable, True -- disable port tx signal + False -- enable port tx signal + @return True when operation success, False on failure. + """ + TX_DISABLE_BYTE_OFFSET = 86 + if port_num not in range(self.port_start, self.port_end + 1) or type(disable) != bool: + return False + + # QSFP, set eeprom to disable tx + if port_num in self.qsfp_ports: + presence = self.get_presence(port_num) + if not presence: + return True + + disable = b'\x0f' if disable else b'\x00' + # open eeprom + try: + with open(self.port_to_eeprom_mapping[port_num], mode="wb", buffering=0) as sysfsfile: + sysfsfile.seek(TX_DISABLE_BYTE_OFFSET) + sysfsfile.write(bytearray(disable)) + except IOError: + return False + + # SFP, set tx_disable pin + else: + try: + disable = hex(1) if disable else hex(0) + port_name = self.get_port_name(port_num) + reg_file = open( + "/".join([self.PORT_INFO_PATH, port_name, "sfp_txdisable"]), "w") + reg_file.write(disable) + reg_file.close() + except IOError as e: + print "Error: unable to open file: %s" % str(e) + return False + + return True + + def reset_all(self): + result = True + port_sysfs_path = [] + for port in range(self.port_start, self.port_end+1): + if port not in self.qsfp_ports: + continue + + presence = self.get_presence(port) + if not presence: + continue + + try: + port_name = self.get_port_name(port) + sysfs_path = "/".join([self.PORT_INFO_PATH, + port_name, "qsfp_reset"]) + reg_file = open(sysfs_path, "w") + port_sysfs_path.append(sysfs_path) + except IOError as e: + result = False + continue + + self._do_write_file(reg_file, 0, 0) + + time.sleep(1) + + for sysfs_path in port_sysfs_path: + try: + reg_file = open(sysfs_path, "w") + except IOError as e: + result = False + continue + + self._do_write_file(reg_file, 0, 1) + + return result diff --git a/device/celestica/x86_64-cel_questone_2-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_questone_2-r0/pmon_daemon_control.json new file mode 100644 index 0000000000..f5b2736b13 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/pmon_daemon_control.json @@ -0,0 +1,5 @@ +{ + "skip_ledd": true, + "skip_fancontrol": true, + "skip_xcvrd_cmis_mgr": true +} diff --git a/device/celestica/x86_64-cel_questone_2-r0/system_health_monitoring_config.json b/device/celestica/x86_64-cel_questone_2-r0/system_health_monitoring_config.json new file mode 100644 index 0000000000..56fda7de4f --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/system_health_monitoring_config.json @@ -0,0 +1,13 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "psu.temperature" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "amber", + "normal": "green", + "booting": "green_blink_1hz" + } +} diff --git a/device/celestica/x86_64-cel_questone_2-r0/warm-reboot_plugin b/device/celestica/x86_64-cel_questone_2-r0/warm-reboot_plugin new file mode 100755 index 0000000000..d0fb8b29e1 --- /dev/null +++ b/device/celestica/x86_64-cel_questone_2-r0/warm-reboot_plugin @@ -0,0 +1,4 @@ +#!/bin/bash + +# Set all LEDs to BMC's control +ipmitool raw 0x3a 0x0f 0x02 0x01 &> /dev/null diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers.json.j2 b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers.json.j2 new file mode 100644 index 0000000000..0b1cb2c541 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers.json.j2 @@ -0,0 +1,2 @@ +{%- set default_topo = 't1' %} +{%- include 'buffers_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_def.j2 b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_def.j2 new file mode 100644 index 0000000000..740cfdf79e --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_def.j2 @@ -0,0 +1,46 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "xoff": "4625920", + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_t0.j2 b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_t0.j2 new file mode 100644 index 0000000000..44fcf21887 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_t0.j2 @@ -0,0 +1,45 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_t1.j2 b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_t1.j2 new file mode 100644 index 0000000000..740cfdf79e --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/buffers_defaults_t1.j2 @@ -0,0 +1,46 @@ +{%- set default_cable = '300m' %} + +{%- macro generate_port_lists(PORT_ALL) %} + {# Generate list of ports #} + {% for port_idx in range(0,32) %} + {% if PORT_ALL.append("Ethernet%d" % (port_idx * 4)) %}{% endif %} + {% endfor %} +{%- endmacro %} + +{%- macro generate_buffer_pool_and_profiles() %} + "BUFFER_POOL": { + "ingress_lossless_pool": { + "xoff": "4625920", + "size": "12766208", + "type": "ingress", + "mode": "dynamic" + }, + "egress_lossless_pool": { + "size": "12766208", + "type": "egress", + "mode": "static" + }, + "egress_lossy_pool": { + "size": "7326924", + "type": "egress", + "mode": "dynamic" + } + }, + "BUFFER_PROFILE": { + "ingress_lossy_profile": { + "pool":"[BUFFER_POOL|ingress_lossless_pool]", + "size":"0", + "dynamic_th":"3" + }, + "egress_lossless_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"0", + "static_th":"12766208" + }, + "egress_lossy_profile": { + "pool":"[BUFFER_POOL|egress_lossless_pool]", + "size":"1518", + "dynamic_th":"3" + } + }, +{%- endmacro %} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/hwsku.json b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/hwsku.json new file mode 100644 index 0000000000..28e50b8c03 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/hwsku.json @@ -0,0 +1,169 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet4": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet12": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet20": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet28": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet36": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet44": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet52": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet60": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet68": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet76": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet84": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet92": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet100": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet108": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet116": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet124": { + "default_brkout_mode": "1x100G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet128": { + "default_brkout_mode": "1x10G", + "autoneg": "off", + "fec": "none" + } + } +} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/l2/config b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/l2/config new file mode 100644 index 0000000000..45a7b84d50 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/l2/config @@ -0,0 +1,3 @@ +l2_mem_entries=139264 +l3_mem_entries=8192 +l3_alpm_enable=0 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/l3/config b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/l3/config new file mode 100644 index 0000000000..3467c1b397 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/l3/config @@ -0,0 +1,3 @@ +l2_mem_entries=40000 +l3_mem_entries=40000 +l3_alpm_enable=2 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/pg_profile_lookup.ini b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/pg_profile_lookup.ini new file mode 100644 index 0000000000..9f2eacb6fc --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/pg_profile_lookup.ini @@ -0,0 +1,17 @@ +# PG lossless profiles. +# speed cable size xon xoff threshold xon_offset + 10000 5m 56368 18432 55120 -3 2496 + 25000 5m 56368 18432 55120 -3 2496 + 40000 5m 56368 18432 55120 -3 2496 + 50000 5m 56368 18432 55120 -3 2496 + 100000 5m 56368 18432 55120 -3 2496 + 10000 40m 56368 18432 55120 -3 2496 + 25000 40m 56368 18432 55120 -3 2496 + 40000 40m 56368 18432 55120 -3 2496 + 50000 40m 56368 18432 55120 -3 2496 + 100000 40m 56368 18432 55120 -3 2496 + 10000 300m 56368 18432 55120 -3 2496 + 25000 300m 56368 18432 55120 -3 2496 + 40000 300m 56368 18432 55120 -3 2496 + 50000 300m 56368 18432 55120 -3 2496 + 100000 300m 56368 18432 55120 -3 2496 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/port_config.ini b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/port_config.ini index 1596faa8af..8cd1c833a9 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/port_config.ini +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/port_config.ini @@ -1,34 +1,34 @@ -# name lanes alias fec index speed -Ethernet0 1,2,3,4 QSFP1 rs 1 100000 -Ethernet4 5,6,7,8 QSFP2 rs 2 100000 -Ethernet8 9,10,11,12 QSFP3 rs 3 100000 -Ethernet12 13,14,15,16 QSFP4 rs 4 100000 -Ethernet16 17,18,19,20 QSFP5 rs 5 100000 -Ethernet20 21,22,23,24 QSFP6 rs 6 100000 -Ethernet24 25,26,27,28 QSFP7 rs 7 100000 -Ethernet28 29,30,31,32 QSFP8 rs 8 100000 -Ethernet32 33,34,35,36 QSFP9 rs 9 100000 -Ethernet36 37,38,39,40 QSFP10 rs 10 100000 -Ethernet40 41,42,43,44 QSFP11 rs 11 100000 -Ethernet44 45,46,47,48 QSFP12 rs 12 100000 -Ethernet48 49,50,51,52 QSFP13 rs 13 100000 -Ethernet52 53,54,55,56 QSFP14 rs 14 100000 -Ethernet56 57,58,59,60 QSFP15 rs 15 100000 -Ethernet60 61,62,63,64 QSFP16 rs 16 100000 -Ethernet64 65,66,67,68 QSFP17 rs 17 100000 -Ethernet68 69,70,71,72 QSFP18 rs 18 100000 -Ethernet72 73,74,75,76 QSFP19 rs 19 100000 -Ethernet76 77,78,79,80 QSFP20 rs 20 100000 -Ethernet80 81,82,83,84 QSFP21 rs 21 100000 -Ethernet84 85,86,87,88 QSFP22 rs 22 100000 -Ethernet88 89,90,91,92 QSFP23 rs 23 100000 -Ethernet92 93,94,95,96 QSFP24 rs 24 100000 -Ethernet96 97,98,99,100 QSFP25 rs 25 100000 -Ethernet100 101,102,103,104 QSFP26 rs 26 100000 -Ethernet104 105,106,107,108 QSFP27 rs 27 100000 -Ethernet108 109,110,111,112 QSFP28 rs 28 100000 -Ethernet112 113,114,115,116 QSFP29 rs 29 100000 -Ethernet116 117,118,119,120 QSFP30 rs 30 100000 -Ethernet120 121,122,123,124 QSFP31 rs 31 100000 -Ethernet124 125,126,127,128 QSFP32 rs 32 100000 -Ethernet128 129 SFP1 none 33 10000 +# name lanes alias index speed valid_speeds +Ethernet0 1,2,3,4 Eth1/1 1 100000 100000,40000 +Ethernet4 5,6,7,8 Eth2/1 2 100000 100000,40000 +Ethernet8 9,10,11,12 Eth3/1 3 100000 100000,40000 +Ethernet12 13,14,15,16 Eth4/1 4 100000 100000,40000 +Ethernet16 17,18,19,20 Eth5/1 5 100000 100000,40000 +Ethernet20 21,22,23,24 Eth6/1 6 100000 100000,40000 +Ethernet24 25,26,27,28 Eth7/1 7 100000 100000,40000 +Ethernet28 29,30,31,32 Eth8/1 8 100000 100000,40000 +Ethernet32 33,34,35,36 Eth9/1 9 100000 100000,40000 +Ethernet36 37,38,39,40 Eth10/1 10 100000 100000,40000 +Ethernet40 41,42,43,44 Eth11/1 11 100000 100000,40000 +Ethernet44 45,46,47,48 Eth12/1 12 100000 100000,40000 +Ethernet48 49,50,51,52 Eth13/1 13 100000 100000,40000 +Ethernet52 53,54,55,56 Eth14/1 14 100000 100000,40000 +Ethernet56 57,58,59,60 Eth15/1 15 100000 100000,40000 +Ethernet60 61,62,63,64 Eth16/1 16 100000 100000,40000 +Ethernet64 65,66,67,68 Eth17/1 17 100000 100000,40000 +Ethernet68 69,70,71,72 Eth18/1 18 100000 100000,40000 +Ethernet72 73,74,75,76 Eth19/1 19 100000 100000,40000 +Ethernet76 77,78,79,80 Eth20/1 20 100000 100000,40000 +Ethernet80 81,82,83,84 Eth21/1 21 100000 100000,40000 +Ethernet84 85,86,87,88 Eth22/1 22 100000 100000,40000 +Ethernet88 89,90,91,92 Eth23/1 23 100000 100000,40000 +Ethernet92 93,94,95,96 Eth24/1 24 100000 100000,40000 +Ethernet96 97,98,99,100 Eth25/1 25 100000 100000,40000 +Ethernet100 101,102,103,104 Eth26/1 26 100000 100000,40000 +Ethernet104 105,106,107,108 Eth27/1 27 100000 100000,40000 +Ethernet108 109,110,111,112 Eth28/1 28 100000 100000,40000 +Ethernet112 113,114,115,116 Eth29/1 29 100000 100000,40000 +Ethernet116 117,118,119,120 Eth30/1 30 100000 100000,40000 +Ethernet120 121,122,123,124 Eth31/1 31 100000 100000,40000 +Ethernet124 125,126,127,128 Eth32/1 32 100000 100000,40000 +Ethernet128 129 Eth33/1 33 10000 10000,1000 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/qos.json.j2 b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/qos.json.j2 new file mode 100644 index 0000000000..3e548325ea --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/qos.json.j2 @@ -0,0 +1 @@ +{%- include 'qos_config.j2' %} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile deleted file mode 100644 index b57101d114..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile +++ /dev/null @@ -1,2 +0,0 @@ -SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G.config.bcm -SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile.j2 b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile.j2 new file mode 100644 index 0000000000..0c9245de7c --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/sai.profile.j2 @@ -0,0 +1,17 @@ +{# Get sai.profile based on vxlan_profile. Vxlan's config.bcm file is the default one #} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G-vxlan.config.bcm' -%} +{%- if DEVICE_METADATA is defined and DEVICE_METADATA['localhost'] is defined -%} +{%- if DEVICE_METADATA['localhost']['vxlan_profile'] is defined -%} +{%- set vxlan_profile = DEVICE_METADATA['localhost']['vxlan_profile'] -%} +{%- if 'enable' in vxlan_profile.lower() %} +{% set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G-vxlan.config.bcm' -%} +{%- else %} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G.config.bcm' -%} +{%- endif %} +{%- else %} +{%- set sai_profile_contents = 'SAI_INIT_CONFIG_FILE=/usr/share/sonic/hwsku/td3-seastone_2-32x100G-vxlan.config.bcm' -%} +{%- endif %} +{%- endif %} +{# Write the contents of sai_profile_filename to sai.profile file #} +{{ sai_profile_contents }} +SAI_NUM_ECMP_MEMBERS=64 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G-vxlan.config.bcm b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G-vxlan.config.bcm new file mode 100644 index 0000000000..83c535a24b --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G-vxlan.config.bcm @@ -0,0 +1,576 @@ +help_cli_enable=1 +ifp_inports_support_enable=1 +ipv6_lpm_128b_enable=0x1 +l2_mem_entries=32768 +l2xmsg_mode=1 +l3_max_ecmp_mode=1 +l3_mem_entries=16384 +lpm_scaling_enable=1 +max_vp_lags=0 +#mem_cache_enable=0 +memlist_enable=1 +reglist_enable=1 +#scache_filename=/tmp/scache +schan_intr_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=3000000 +miim_intr_enable=0 +module_64ports=1 +oversubscribe_mode=1 +parity_enable=0 +serdes_lane_config_dfe=on +#serdes_fec_enable=1 +serdes_if_type_ce=14 +pbmp_gport_stack.0=0x0000000000000000000000000000000000000000000000000000000000000000 +pbmp_xport_xe=0x3ffffffffffffffffffffffffffffffffe +port_flex_enable=1 + +ptp_ts_pll_fref=50000000 +ptp_bs_fref_0=50000000 +ptp_bs_fref_1=50000000 +bcm_tunnel_term_compatible_mode=1 +phy_an_c73=1 + +portmap_1=1:100 +portmap_5=5:100 +portmap_9=9:100 +portmap_13=13:100 +portmap_17=17:100 +portmap_21=21:100 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:100 +portmap_45=45:100 +portmap_49=49:100 +portmap_53=53:100 +portmap_57=57:100 +portmap_61=61:100 +portmap_67=65:100 +portmap_71=69:100 +portmap_75=73:100 +portmap_79=77:100 +portmap_83=81:100 +portmap_87=85:100 +portmap_91=89:100 +portmap_95=93:100 +portmap_99=97:100 +portmap_103=101:100 +portmap_107=105:100 +portmap_111=109:100 +portmap_115=113:100 +portmap_119=117:100 +portmap_123=121:100 +portmap_127=125:100 +portmap_66=129:10:m +#portmap_130=128:10:m + +#wc0 lane swap +phy_chain_tx_lane_map_physical{1.0}=0x0132 +phy_chain_rx_lane_map_physical{1.0}=0x3210 + +#wc1 lane swap +phy_chain_tx_lane_map_physical{5.0}=0x2301 +phy_chain_rx_lane_map_physical{5.0}=0x2031 + +#wc2 lane swap +phy_chain_tx_lane_map_physical{9.0}=0x0132 +phy_chain_rx_lane_map_physical{9.0}=0x3210 + +#wc3 lane swap +phy_chain_tx_lane_map_physical{13.0}=0x3201 +phy_chain_rx_lane_map_physical{13.0}=0x2031 + +#wc4 lane swap +phy_chain_tx_lane_map_physical{17.0}=0x0123 +phy_chain_rx_lane_map_physical{17.0}=0x3210 + +#wc5 lane swap +phy_chain_tx_lane_map_physical{21.0}=0x2301 +phy_chain_rx_lane_map_physical{21.0}=0x2031 + +#wc6 lane swap +phy_chain_tx_lane_map_physical{25.0}=0x0123 +phy_chain_rx_lane_map_physical{25.0}=0x3210 + +#wc7 lane swap +phy_chain_tx_lane_map_physical{29.0}=0x3201 +phy_chain_rx_lane_map_physical{29.0}=0x2031 + +#wc8 lane swap +phy_chain_tx_lane_map_physical{33.0}=0x0213 +phy_chain_rx_lane_map_physical{33.0}=0x1302 + +#wc9 lane swap +phy_chain_tx_lane_map_physical{37.0}=0x1302 +phy_chain_rx_lane_map_physical{37.0}=0x2031 + +#wc10 lane swap +phy_chain_tx_lane_map_physical{41.0}=0x0231 +phy_chain_rx_lane_map_physical{41.0}=0x3120 + +#wc11 lane swap +phy_chain_tx_lane_map_physical{45.0}=0x1302 +phy_chain_rx_lane_map_physical{45.0}=0x2031 + +#wc12 lane swap +phy_chain_tx_lane_map_physical{49.0}=0x2103 +phy_chain_rx_lane_map_physical{49.0}=0x3120 + +#wc13 lane swap +phy_chain_tx_lane_map_physical{53.0}=0x2301 +phy_chain_rx_lane_map_physical{53.0}=0x2031 + +#wc14 lane swap +phy_chain_tx_lane_map_physical{57.0}=0x0123 +phy_chain_rx_lane_map_physical{57.0}=0x2301 + +#wc15 lane swap +phy_chain_tx_lane_map_physical{61.0}=0x3210 +phy_chain_rx_lane_map_physical{61.0}=0x1032 + +#wc16 lane swap +phy_chain_tx_lane_map_physical{65.0}=0x3210 +phy_chain_rx_lane_map_physical{65.0}=0x1023 + +#wc17 lane swap +phy_chain_tx_lane_map_physical{69.0}=0x0123 +phy_chain_rx_lane_map_physical{69.0}=0x1302 + +#wc18 lane swap +phy_chain_tx_lane_map_physical{73.0}=0x2301 +phy_chain_rx_lane_map_physical{73.0}=0x1032 + +#wc19 lane swap +phy_chain_tx_lane_map_physical{77.0}=0x2013 +phy_chain_rx_lane_map_physical{77.0}=0x3120 + +#wc20 lane swap +phy_chain_tx_lane_map_physical{81.0}=0x1302 +phy_chain_rx_lane_map_physical{81.0}=0x2031 + +#wc21 lane swap +phy_chain_tx_lane_map_physical{85.0}=0x0123 +phy_chain_rx_lane_map_physical{85.0}=0x2130 + +#wc22 lane swap +phy_chain_tx_lane_map_physical{89.0}=0x2301 +phy_chain_rx_lane_map_physical{89.0}=0x2031 + +#wc23 lane swap +phy_chain_tx_lane_map_physical{93.0}=0x0312 +phy_chain_rx_lane_map_physical{93.0}=0x2310 + +#wc24 lane swap +phy_chain_tx_lane_map_physical{97.0}=0x2301 +phy_chain_rx_lane_map_physical{97.0}=0x1032 + +#wc25 lane swap +phy_chain_tx_lane_map_physical{101.0}=0x0123 +phy_chain_rx_lane_map_physical{101.0}=0x3210 + +#wc26 lane swap +phy_chain_tx_lane_map_physical{105.0}=0x2301 +phy_chain_rx_lane_map_physical{105.0}=0x1032 + +#wc27 lane swap +phy_chain_tx_lane_map_physical{109.0}=0x0123 +phy_chain_rx_lane_map_physical{109.0}=0x3210 + +#wc28 lane swap +phy_chain_tx_lane_map_physical{113.0}=0x2301 +phy_chain_rx_lane_map_physical{113.0}=0x2031 + +#wc29 lane swap +phy_chain_tx_lane_map_physical{117.0}=0x0123 +phy_chain_rx_lane_map_physical{117.0}=0x3210 + +#wc30 lane swap +phy_chain_tx_lane_map_physical{121.0}=0x2301 +phy_chain_rx_lane_map_physical{121.0}=0x1032 + +#wc31 lane swap +phy_chain_tx_lane_map_physical{125.0}=0x0123 +phy_chain_rx_lane_map_physical{125.0}=0x3210 + +#MC lane swap +phy_chain_tx_lane_map_physical{129.0}=0x3210 +phy_chain_rx_lane_map_physical{129.0}=0x0231 + + +#wc0 P/N flip +phy_chain_tx_polarity_flip_physical{1.0}=0x0 +phy_chain_rx_polarity_flip_physical{1.0}=0x0 +phy_chain_tx_polarity_flip_physical{2.0}=0x0 +phy_chain_rx_polarity_flip_physical{2.0}=0x1 +phy_chain_tx_polarity_flip_physical{3.0}=0x0 +phy_chain_rx_polarity_flip_physical{3.0}=0x0 +phy_chain_tx_polarity_flip_physical{4.0}=0x1 +phy_chain_rx_polarity_flip_physical{4.0}=0x1 + +#wc1 P/N flip +phy_chain_tx_polarity_flip_physical{5.0}=0x0 +phy_chain_rx_polarity_flip_physical{5.0}=0x0 +phy_chain_tx_polarity_flip_physical{6.0}=0x1 +phy_chain_rx_polarity_flip_physical{6.0}=0x1 +phy_chain_tx_polarity_flip_physical{7.0}=0x0 +phy_chain_rx_polarity_flip_physical{7.0}=0x1 +phy_chain_tx_polarity_flip_physical{8.0}=0x1 +phy_chain_rx_polarity_flip_physical{8.0}=0x1 + +#wc2 P/N flip +phy_chain_tx_polarity_flip_physical{9.0}=0x0 +phy_chain_rx_polarity_flip_physical{9.0}=0x0 +phy_chain_tx_polarity_flip_physical{10.0}=0x0 +phy_chain_rx_polarity_flip_physical{10.0}=0x1 +phy_chain_tx_polarity_flip_physical{11.0}=0x0 +phy_chain_rx_polarity_flip_physical{11.0}=0x0 +phy_chain_tx_polarity_flip_physical{12.0}=0x1 +phy_chain_rx_polarity_flip_physical{12.0}=0x1 + +#wc3 P/N flip +phy_chain_tx_polarity_flip_physical{13.0}=0x0 +phy_chain_rx_polarity_flip_physical{13.0}=0x0 +phy_chain_tx_polarity_flip_physical{14.0}=0x1 +phy_chain_rx_polarity_flip_physical{14.0}=0x1 +phy_chain_tx_polarity_flip_physical{15.0}=0x0 +phy_chain_rx_polarity_flip_physical{15.0}=0x1 +phy_chain_tx_polarity_flip_physical{16.0}=0x0 +phy_chain_rx_polarity_flip_physical{16.0}=0x1 + +#wc4 P/N flip +phy_chain_tx_polarity_flip_physical{17.0}=0x0 +phy_chain_rx_polarity_flip_physical{17.0}=0x0 +phy_chain_tx_polarity_flip_physical{18.0}=0x1 +phy_chain_rx_polarity_flip_physical{18.0}=0x1 +phy_chain_tx_polarity_flip_physical{19.0}=0x0 +phy_chain_rx_polarity_flip_physical{19.0}=0x0 +phy_chain_tx_polarity_flip_physical{20.0}=0x1 +phy_chain_rx_polarity_flip_physical{20.0}=0x1 + +#wc5 P/N flip +phy_chain_tx_polarity_flip_physical{21.0}=0x0 +phy_chain_rx_polarity_flip_physical{21.0}=0x0 +phy_chain_tx_polarity_flip_physical{22.0}=0x1 +phy_chain_rx_polarity_flip_physical{22.0}=0x1 +phy_chain_tx_polarity_flip_physical{23.0}=0x0 +phy_chain_rx_polarity_flip_physical{23.0}=0x1 +phy_chain_tx_polarity_flip_physical{24.0}=0x1 +phy_chain_rx_polarity_flip_physical{24.0}=0x1 + +#wc6 P/N flip +phy_chain_tx_polarity_flip_physical{25.0}=0x0 +phy_chain_rx_polarity_flip_physical{25.0}=0x1 +phy_chain_tx_polarity_flip_physical{26.0}=0x1 +phy_chain_rx_polarity_flip_physical{26.0}=0x0 +phy_chain_tx_polarity_flip_physical{27.0}=0x0 +phy_chain_rx_polarity_flip_physical{27.0}=0x1 +phy_chain_tx_polarity_flip_physical{28.0}=0x1 +phy_chain_rx_polarity_flip_physical{28.0}=0x0 + +#wc7 P/N flip +phy_chain_tx_polarity_flip_physical{29.0}=0x1 +phy_chain_rx_polarity_flip_physical{29.0}=0x1 +phy_chain_tx_polarity_flip_physical{30.0}=0x1 +phy_chain_rx_polarity_flip_physical{30.0}=0x0 +phy_chain_tx_polarity_flip_physical{31.0}=0x0 +phy_chain_rx_polarity_flip_physical{31.0}=0x0 +phy_chain_tx_polarity_flip_physical{32.0}=0x0 +phy_chain_rx_polarity_flip_physical{32.0}=0x0 + +#wc8 P/N flip +phy_chain_tx_polarity_flip_physical{33.0}=0x1 +phy_chain_rx_polarity_flip_physical{33.0}=0x1 +phy_chain_tx_polarity_flip_physical{34.0}=0x0 +phy_chain_rx_polarity_flip_physical{34.0}=0x0 +phy_chain_tx_polarity_flip_physical{35.0}=0x0 +phy_chain_rx_polarity_flip_physical{35.0}=0x0 +phy_chain_tx_polarity_flip_physical{36.0}=0x1 +phy_chain_rx_polarity_flip_physical{36.0}=0x0 + +#wc9 P/N flip +phy_chain_tx_polarity_flip_physical{37.0}=0x1 +phy_chain_rx_polarity_flip_physical{37.0}=0x1 +phy_chain_tx_polarity_flip_physical{38.0}=0x1 +phy_chain_rx_polarity_flip_physical{38.0}=0x0 +phy_chain_tx_polarity_flip_physical{39.0}=0x1 +phy_chain_rx_polarity_flip_physical{39.0}=0x0 +phy_chain_tx_polarity_flip_physical{40.0}=0x0 +phy_chain_rx_polarity_flip_physical{40.0}=0x1 + +#wc10 P/N flip +phy_chain_tx_polarity_flip_physical{41.0}=0x1 +phy_chain_rx_polarity_flip_physical{41.0}=0x1 +phy_chain_tx_polarity_flip_physical{42.0}=0x0 +phy_chain_rx_polarity_flip_physical{42.0}=0x1 +phy_chain_tx_polarity_flip_physical{43.0}=0x1 +phy_chain_rx_polarity_flip_physical{43.0}=0x0 +phy_chain_tx_polarity_flip_physical{44.0}=0x1 +phy_chain_rx_polarity_flip_physical{44.0}=0x1 + +#wc11 P/N flip +phy_chain_tx_polarity_flip_physical{45.0}=0x1 +phy_chain_rx_polarity_flip_physical{45.0}=0x0 +phy_chain_tx_polarity_flip_physical{46.0}=0x1 +phy_chain_rx_polarity_flip_physical{46.0}=0x0 +phy_chain_tx_polarity_flip_physical{47.0}=0x1 +phy_chain_rx_polarity_flip_physical{47.0}=0x1 +phy_chain_tx_polarity_flip_physical{48.0}=0x0 +phy_chain_rx_polarity_flip_physical{48.0}=0x1 + +#wc12 P/N flip +phy_chain_tx_polarity_flip_physical{49.0}=0x1 +phy_chain_rx_polarity_flip_physical{49.0}=0x0 +phy_chain_tx_polarity_flip_physical{50.0}=0x1 +phy_chain_rx_polarity_flip_physical{50.0}=0x0 +phy_chain_tx_polarity_flip_physical{51.0}=0x0 +phy_chain_rx_polarity_flip_physical{51.0}=0x1 +phy_chain_tx_polarity_flip_physical{52.0}=0x1 +phy_chain_rx_polarity_flip_physical{52.0}=0x1 + +#wc13 P/N flip +phy_chain_tx_polarity_flip_physical{53.0}=0x0 +phy_chain_rx_polarity_flip_physical{53.0}=0x0 +phy_chain_tx_polarity_flip_physical{54.0}=0x1 +phy_chain_rx_polarity_flip_physical{54.0}=0x1 +phy_chain_tx_polarity_flip_physical{55.0}=0x0 +phy_chain_rx_polarity_flip_physical{55.0}=0x1 +phy_chain_tx_polarity_flip_physical{56.0}=0x1 +phy_chain_rx_polarity_flip_physical{56.0}=0x1 + +#wc14 P/N flip +phy_chain_tx_polarity_flip_physical{57.0}=0x1 +phy_chain_rx_polarity_flip_physical{57.0}=0x0 +phy_chain_tx_polarity_flip_physical{58.0}=0x1 +phy_chain_rx_polarity_flip_physical{58.0}=0x1 +phy_chain_tx_polarity_flip_physical{59.0}=0x0 +phy_chain_rx_polarity_flip_physical{59.0}=0x0 +phy_chain_tx_polarity_flip_physical{60.0}=0x1 +phy_chain_rx_polarity_flip_physical{60.0}=0x1 + +#wc15 P/N flip +phy_chain_tx_polarity_flip_physical{61.0}=0x0 +phy_chain_rx_polarity_flip_physical{61.0}=0x1 +phy_chain_tx_polarity_flip_physical{62.0}=0x1 +phy_chain_rx_polarity_flip_physical{62.0}=0x0 +phy_chain_tx_polarity_flip_physical{63.0}=0x0 +phy_chain_rx_polarity_flip_physical{63.0}=0x1 +phy_chain_tx_polarity_flip_physical{64.0}=0x0 +phy_chain_rx_polarity_flip_physical{64.0}=0x0 + +#wc16 P/N flip +phy_chain_tx_polarity_flip_physical{65.0}=0x1 +phy_chain_rx_polarity_flip_physical{65.0}=0x0 +phy_chain_tx_polarity_flip_physical{66.0}=0x0 +phy_chain_rx_polarity_flip_physical{66.0}=0x0 +phy_chain_tx_polarity_flip_physical{67.0}=0x1 +phy_chain_rx_polarity_flip_physical{67.0}=0x1 +phy_chain_tx_polarity_flip_physical{68.0}=0x0 +phy_chain_rx_polarity_flip_physical{68.0}=0x0 + +#wc17 P/N flip +phy_chain_tx_polarity_flip_physical{69.0}=0x1 +phy_chain_rx_polarity_flip_physical{69.0}=0x1 +phy_chain_tx_polarity_flip_physical{70.0}=0x0 +phy_chain_rx_polarity_flip_physical{70.0}=0x0 +phy_chain_tx_polarity_flip_physical{71.0}=0x1 +phy_chain_rx_polarity_flip_physical{71.0}=0x0 +phy_chain_tx_polarity_flip_physical{72.0}=0x0 +phy_chain_rx_polarity_flip_physical{72.0}=0x0 + +#wc18 P/N flip +phy_chain_tx_polarity_flip_physical{73.0}=0x0 +phy_chain_rx_polarity_flip_physical{73.0}=0x1 +phy_chain_tx_polarity_flip_physical{74.0}=0x1 +phy_chain_rx_polarity_flip_physical{74.0}=0x0 +phy_chain_tx_polarity_flip_physical{75.0}=0x0 +phy_chain_rx_polarity_flip_physical{75.0}=0x1 +phy_chain_tx_polarity_flip_physical{76.0}=0x1 +phy_chain_rx_polarity_flip_physical{76.0}=0x0 + +#wc19 P/N flip +phy_chain_tx_polarity_flip_physical{77.0}=0x0 +phy_chain_rx_polarity_flip_physical{77.0}=0x0 +phy_chain_tx_polarity_flip_physical{78.0}=0x0 +phy_chain_rx_polarity_flip_physical{78.0}=0x0 +phy_chain_tx_polarity_flip_physical{79.0}=0x1 +phy_chain_rx_polarity_flip_physical{79.0}=0x1 +phy_chain_tx_polarity_flip_physical{80.0}=0x1 +phy_chain_rx_polarity_flip_physical{80.0}=0x1 + +#wc20 P/N flip +phy_chain_tx_polarity_flip_physical{81.0}=0x0 +phy_chain_rx_polarity_flip_physical{81.0}=0x0 +phy_chain_tx_polarity_flip_physical{82.0}=0x0 +phy_chain_rx_polarity_flip_physical{82.0}=0x0 +phy_chain_tx_polarity_flip_physical{83.0}=0x1 +phy_chain_rx_polarity_flip_physical{83.0}=0x1 +phy_chain_tx_polarity_flip_physical{84.0}=0x1 +phy_chain_rx_polarity_flip_physical{84.0}=0x0 + +#wc21 P/N flip +phy_chain_tx_polarity_flip_physical{85.0}=0x1 +phy_chain_rx_polarity_flip_physical{85.0}=0x1 +phy_chain_tx_polarity_flip_physical{86.0}=0x0 +phy_chain_rx_polarity_flip_physical{86.0}=0x1 +phy_chain_tx_polarity_flip_physical{87.0}=0x1 +phy_chain_rx_polarity_flip_physical{87.0}=0x0 +phy_chain_tx_polarity_flip_physical{88.0}=0x0 +phy_chain_rx_polarity_flip_physical{88.0}=0x0 + +#wc22 P/N flip +phy_chain_tx_polarity_flip_physical{89.0}=0x1 +phy_chain_rx_polarity_flip_physical{89.0}=0x0 +phy_chain_tx_polarity_flip_physical{90.0}=0x0 +phy_chain_rx_polarity_flip_physical{90.0}=0x0 +phy_chain_tx_polarity_flip_physical{91.0}=0x1 +phy_chain_rx_polarity_flip_physical{91.0}=0x1 +phy_chain_tx_polarity_flip_physical{92.0}=0x0 +phy_chain_rx_polarity_flip_physical{92.0}=0x1 + +#wc23 P/N flip +phy_chain_tx_polarity_flip_physical{93.0}=0x1 +phy_chain_rx_polarity_flip_physical{93.0}=0x1 +phy_chain_tx_polarity_flip_physical{94.0}=0x1 +phy_chain_rx_polarity_flip_physical{94.0}=0x1 +phy_chain_tx_polarity_flip_physical{95.0}=0x0 +phy_chain_rx_polarity_flip_physical{95.0}=0x0 +phy_chain_tx_polarity_flip_physical{96.0}=0x0 +phy_chain_rx_polarity_flip_physical{96.0}=0x1 + +#wc24 P/N flip +phy_chain_tx_polarity_flip_physical{97.0}=0x1 +phy_chain_rx_polarity_flip_physical{97.0}=0x1 +phy_chain_tx_polarity_flip_physical{98.0}=0x0 +phy_chain_rx_polarity_flip_physical{98.0}=0x0 +phy_chain_tx_polarity_flip_physical{99.0}=0x1 +phy_chain_rx_polarity_flip_physical{99.0}=0x1 +phy_chain_tx_polarity_flip_physical{100.0}=0x0 +phy_chain_rx_polarity_flip_physical{100.0}=0x0 + +#wc25 P/N flip +phy_chain_tx_polarity_flip_physical{101.0}=0x1 +phy_chain_rx_polarity_flip_physical{101.0}=0x0 +phy_chain_tx_polarity_flip_physical{102.0}=0x0 +phy_chain_rx_polarity_flip_physical{102.0}=0x1 +phy_chain_tx_polarity_flip_physical{103.0}=0x1 +phy_chain_rx_polarity_flip_physical{103.0}=0x0 +phy_chain_tx_polarity_flip_physical{104.0}=0x0 +phy_chain_rx_polarity_flip_physical{104.0}=0x0 + +#wc26 P/N flip +phy_chain_tx_polarity_flip_physical{105.0}=0x1 +phy_chain_rx_polarity_flip_physical{105.0}=0x0 +phy_chain_tx_polarity_flip_physical{106.0}=0x0 +phy_chain_rx_polarity_flip_physical{106.0}=0x1 +phy_chain_tx_polarity_flip_physical{107.0}=0x1 +phy_chain_rx_polarity_flip_physical{107.0}=0x0 +phy_chain_tx_polarity_flip_physical{108.0}=0x0 +phy_chain_rx_polarity_flip_physical{108.0}=0x1 + +#wc27 P/N flip +phy_chain_tx_polarity_flip_physical{109.0}=0x1 +phy_chain_rx_polarity_flip_physical{109.0}=0x1 +phy_chain_tx_polarity_flip_physical{110.0}=0x0 +phy_chain_rx_polarity_flip_physical{110.0}=0x0 +phy_chain_tx_polarity_flip_physical{111.0}=0x1 +phy_chain_rx_polarity_flip_physical{111.0}=0x1 +phy_chain_tx_polarity_flip_physical{112.0}=0x0 +phy_chain_rx_polarity_flip_physical{112.0}=0x0 + +#wc28 P/N flip +phy_chain_tx_polarity_flip_physical{113.0}=0x1 +phy_chain_rx_polarity_flip_physical{113.0}=0x1 +phy_chain_tx_polarity_flip_physical{114.0}=0x0 +phy_chain_rx_polarity_flip_physical{114.0}=0x0 +phy_chain_tx_polarity_flip_physical{115.0}=0x1 +phy_chain_rx_polarity_flip_physical{115.0}=0x0 +phy_chain_tx_polarity_flip_physical{116.0}=0x0 +phy_chain_rx_polarity_flip_physical{116.0}=0x0 + +#wc29 P/N flip +phy_chain_tx_polarity_flip_physical{117.0}=0x1 +phy_chain_rx_polarity_flip_physical{117.0}=0x1 +phy_chain_tx_polarity_flip_physical{118.0}=0x0 +phy_chain_rx_polarity_flip_physical{118.0}=0x0 +phy_chain_tx_polarity_flip_physical{119.0}=0x1 +phy_chain_rx_polarity_flip_physical{119.0}=0x1 +phy_chain_tx_polarity_flip_physical{120.0}=0x0 +phy_chain_rx_polarity_flip_physical{120.0}=0x0 + +#wc30 P/N flip +phy_chain_tx_polarity_flip_physical{121.0}=0x1 +phy_chain_rx_polarity_flip_physical{121.0}=0x0 +phy_chain_tx_polarity_flip_physical{122.0}=0x0 +phy_chain_rx_polarity_flip_physical{122.0}=0x1 +phy_chain_tx_polarity_flip_physical{123.0}=0x1 +phy_chain_rx_polarity_flip_physical{123.0}=0x0 +phy_chain_tx_polarity_flip_physical{124.0}=0x0 +phy_chain_rx_polarity_flip_physical{124.0}=0x1 + +#wc31 P/N flip +phy_chain_tx_polarity_flip_physical{125.0}=0x1 +phy_chain_rx_polarity_flip_physical{125.0}=0x1 +phy_chain_tx_polarity_flip_physical{126.0}=0x0 +phy_chain_rx_polarity_flip_physical{126.0}=0x0 +phy_chain_tx_polarity_flip_physical{127.0}=0x1 +phy_chain_rx_polarity_flip_physical{127.0}=0x1 +phy_chain_tx_polarity_flip_physical{128.0}=0x0 +phy_chain_rx_polarity_flip_physical{128.0}=0x0 + +#MC P/N flip +phy_chain_tx_polarity_flip_physical{129.0}=0x1 +phy_chain_rx_polarity_flip_physical{129.0}=0x0 +phy_chain_tx_polarity_flip_physical{130.0}=0x0 +phy_chain_rx_polarity_flip_physical{130.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 +phy_chain_tx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x1 + + +# configuration for 100G optical module +serdes_preemphasis_1=0x164608 +serdes_preemphasis_5=0x164608 +serdes_preemphasis_9=0x164608 +serdes_preemphasis_13=0x134908 +serdes_preemphasis_17=0x134908 +serdes_preemphasis_21=0x134908 +serdes_preemphasis_25=0x124a08 +serdes_preemphasis_29=0x124a08 +serdes_preemphasis_33=0x114b08 +serdes_preemphasis_37=0x114b08 +serdes_preemphasis_41=0x0f4d08 +serdes_preemphasis_45=0x0f4d08 +serdes_preemphasis_49=0x0d4f08 +serdes_preemphasis_53=0x0d4f08 +serdes_preemphasis_57=0x0d4f08 +serdes_preemphasis_61=0x0d4f08 +serdes_preemphasis_67=0x0d4f08 +serdes_preemphasis_71=0x0d4f08 +serdes_preemphasis_75=0x0d4f08 +serdes_preemphasis_79=0x0d4f08 +serdes_preemphasis_83=0x0d4f08 +serdes_preemphasis_87=0x0f4d08 +serdes_preemphasis_91=0x0f4d08 +serdes_preemphasis_95=0x0f4d08 +serdes_preemphasis_99=0x114b08 +serdes_preemphasis_103=0x114b08 +serdes_preemphasis_107=0x114b08 +serdes_preemphasis_111=0x124a08 +serdes_preemphasis_115=0x134908 +serdes_preemphasis_119=0x134908 +serdes_preemphasis_123=0x134908 +serdes_preemphasis_127=0x164608 + +#VxLAN +sai_tunnel_support=1 +use_all_splithorizon_groups=1 +bcm_tunnel_term_compatible_mode=1 +flow_init_mode=1 +l3_ecmp_levels=2 +riot_enable=1 +riot_overlay_l3_intf_mem_size=8192 +riot_overlay_l3_egress_mem_size=32768 +riot_overlay_ecmp_resilient_hash_size=16384 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm index d9d2f47750..7803fa422f 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm +++ b/device/celestica/x86_64-cel_seastone_2-r0/Seastone_2/td3-seastone_2-32x100G.config.bcm @@ -1,4 +1,3 @@ -sai_load_hw_config=/etc/bcm/flex/bcm56870_a0_premium_issu/b870.6.4.1/ help_cli_enable=1 ifp_inports_support_enable=1 ipv6_lpm_128b_enable=0x1 @@ -8,8 +7,13 @@ l3_max_ecmp_mode=1 l3_mem_entries=16384 lpm_scaling_enable=1 max_vp_lags=0 -mem_cache_enable=0 +#mem_cache_enable=0 memlist_enable=1 +reglist_enable=1 +#scache_filename=/tmp/scache +schan_intr_enable=0 +stable_size=0x5500000 +tdma_timeout_usec=3000000 miim_intr_enable=0 module_64ports=1 oversubscribe_mode=1 @@ -18,47 +22,49 @@ serdes_lane_config_dfe=on #serdes_fec_enable=1 serdes_if_type_ce=14 pbmp_gport_stack.0=0x0000000000000000000000000000000000000000000000000000000000000000 -pbmp_xport_xe=0x888888888888888c2222222222222222 +pbmp_xport_xe=0x3ffffffffffffffffffffffffffffffffe +port_flex_enable=1 ptp_ts_pll_fref=50000000 ptp_bs_fref_0=50000000 ptp_bs_fref_1=50000000 +bcm_tunnel_term_compatible_mode=1 +phy_an_c73=1 -portmap_1.0=1:100 -portmap_5.0=5:100 -portmap_9.0=9:100 -portmap_13.0=13:100 -portmap_17.0=17:100 -portmap_21.0=21:100 -portmap_25.0=25:100 -portmap_29.0=29:100 -portmap_33.0=33:100 -portmap_37.0=37:100 -portmap_41.0=41:100 -portmap_45.0=45:100 -portmap_49.0=49:100 -portmap_53.0=53:100 -portmap_57.0=57:100 -portmap_61.0=61:100 - -portmap_67.0=65:100 -portmap_71.0=69:100 -portmap_75.0=73:100 -portmap_79.0=77:100 -portmap_83.0=81:100 -portmap_87.0=85:100 -portmap_91.0=89:100 -portmap_95.0=93:100 -portmap_99.0=97:100 -portmap_103.0=101:100 -portmap_107.0=105:100 -portmap_111.0=109:100 -portmap_115.0=113:100 -portmap_119.0=117:100 -portmap_123.0=121:100 -portmap_127.0=125:100 -portmap_66.0=129:10:m -#portmap_130.0=128:10:m +portmap_1=1:100 +portmap_5=5:100 +portmap_9=9:100 +portmap_13=13:100 +portmap_17=17:100 +portmap_21=21:100 +portmap_25=25:100 +portmap_29=29:100 +portmap_33=33:100 +portmap_37=37:100 +portmap_41=41:100 +portmap_45=45:100 +portmap_49=49:100 +portmap_53=53:100 +portmap_57=57:100 +portmap_61=61:100 +portmap_67=65:100 +portmap_71=69:100 +portmap_75=73:100 +portmap_79=77:100 +portmap_83=81:100 +portmap_87=85:100 +portmap_91=89:100 +portmap_95=93:100 +portmap_99=97:100 +portmap_103=101:100 +portmap_107=105:100 +portmap_111=109:100 +portmap_115=113:100 +portmap_119=117:100 +portmap_123=121:100 +portmap_127=125:100 +portmap_66=129:10:m +#portmap_130=128:10:m #wc0 lane swap phy_chain_tx_lane_map_physical{1.0}=0x0132 @@ -518,45 +524,11 @@ phy_chain_tx_polarity_flip_physical{129.0}=0x1 phy_chain_rx_polarity_flip_physical{129.0}=0x0 phy_chain_tx_polarity_flip_physical{130.0}=0x0 phy_chain_rx_polarity_flip_physical{130.0}=0x0 -phy_chain_tx_polarity_flip_physical{131.0}=0x0 -phy_chain_rx_polarity_flip_physical{131.0}=0x0 +phy_chain_tx_polarity_flip_physical{131.0}=0x1 +phy_chain_rx_polarity_flip_physical{131.0}=0x1 phy_chain_tx_polarity_flip_physical{132.0}=0x0 -phy_chain_rx_polarity_flip_physical{132.0}=0x0 +phy_chain_rx_polarity_flip_physical{132.0}=0x1 -dport_map_port_1=1 -dport_map_port_5=2 -dport_map_port_9=3 -dport_map_port_13=4 -dport_map_port_17=5 -dport_map_port_21=6 -dport_map_port_25=7 -dport_map_port_29=8 -dport_map_port_33=9 -dport_map_port_37=10 -dport_map_port_41=11 -dport_map_port_45=12 -dport_map_port_49=13 -dport_map_port_53=14 -dport_map_port_57=15 -dport_map_port_61=16 -dport_map_port_67=17 -dport_map_port_71=18 -dport_map_port_75=19 -dport_map_port_79=20 -dport_map_port_83=21 -dport_map_port_87=22 -dport_map_port_91=23 -dport_map_port_95=24 -dport_map_port_99=25 -dport_map_port_103=26 -dport_map_port_107=27 -dport_map_port_111=28 -dport_map_port_115=29 -dport_map_port_119=30 -dport_map_port_123=31 -dport_map_port_127=32 -dport_map_port_66=33 -#dport_map_port_130=34 # configuration for 100G optical module serdes_preemphasis_1=0x164608 @@ -592,8 +564,3 @@ serdes_preemphasis_119=0x134908 serdes_preemphasis_123=0x134908 serdes_preemphasis_127=0x164608 -reglist_enable=1 -scache_filename=/tmp/scache -schan_intr_enable=0 -stable_size=0x5500000 -tdma_timeout_usec=3000000 diff --git a/device/celestica/x86_64-cel_seastone_2-r0/custom.bin b/device/celestica/x86_64-cel_seastone_2-r0/custom_led.bin similarity index 100% rename from device/celestica/x86_64-cel_seastone_2-r0/custom.bin rename to device/celestica/x86_64-cel_seastone_2-r0/custom_led.bin diff --git a/device/celestica/x86_64-cel_seastone_2-r0/installer.conf b/device/celestica/x86_64-cel_seastone_2-r0/installer.conf index 3222a45fe1..1d21376ff5 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/installer.conf +++ b/device/celestica/x86_64-cel_seastone_2-r0/installer.conf @@ -1,3 +1,4 @@ +CONSOLE_PORT=0xe060 CONSOLE_DEV=0 CONSOLE_SPEED=115200 -ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="earlycon=uart8250,mmio,0xdf37b000" \ No newline at end of file +ONIE_PLATFORM_EXTRA_CMDLINE_LINUX="intel_iommu=off thermal.off=1 noirqdebug acpi_no_watchdog earlycon=uart8250,mmio,0xdf37b000" diff --git a/device/celestica/x86_64-cel_seastone_2-r0/led_proc_init.soc b/device/celestica/x86_64-cel_seastone_2-r0/led_proc_init.soc index b6b474bd53..90aa9ba607 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/led_proc_init.soc +++ b/device/celestica/x86_64-cel_seastone_2-r0/led_proc_init.soc @@ -1,5 +1,2 @@ -linkscan off -m0 load 0 0x3800 /usr/share/sonic/platform/custom.bin -sleep 10 +m0 load 0 0x3800 /usr/share/sonic/platform/custom_led.bin led auto on; led start -linkscan on diff --git a/device/celestica/x86_64-cel_seastone_2-r0/pcie.yaml b/device/celestica/x86_64-cel_seastone_2-r0/pcie.yaml new file mode 100644 index 0000000000..95e9b69547 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/pcie.yaml @@ -0,0 +1,153 @@ +- bus: '00' + dev: '00' + fn: '0' + id: '1980' + name: 'Host bridge: Intel Corporation Atom Processor C3000 Series System Agent (rev + 11)' +- bus: '00' + dev: '04' + fn: '0' + id: 19a1 + name: 'Host bridge: Intel Corporation Atom Processor C3000 Series Error Registers + (rev 11)' +- bus: '00' + dev: '05' + fn: '0' + id: 19a2 + name: 'Generic system peripheral [0807]: Intel Corporation Atom Processor C3000 + Series Root Complex Event Collector (rev 11)' +- bus: '00' + dev: '06' + fn: '0' + id: 19a3 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated QAT + Root Port (rev 11)' +- bus: '00' + dev: 09 + fn: '0' + id: 19a4 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #0 (rev 11)' +- bus: '00' + dev: '10' + fn: '0' + id: 19aa + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #6 (rev 11)' +- bus: '00' + dev: '11' + fn: '0' + id: 19ab + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series PCI Express Root + Port #7 (rev 11)' +- bus: '00' + dev: '12' + fn: '0' + id: 19ac + name: 'System peripheral: Intel Corporation Atom Processor C3000 Series SMBus Contoller + - Host (rev 11)' +- bus: '00' + dev: '14' + fn: '0' + id: 19c2 + name: 'SATA controller: Intel Corporation Atom Processor C3000 Series SATA Controller + 1 (rev 11)' +- bus: '00' + dev: '15' + fn: '0' + id: 19d0 + name: 'USB controller: Intel Corporation Atom Processor C3000 Series USB 3.0 xHCI + Controller (rev 11)' +- bus: '00' + dev: '16' + fn: '0' + id: 19d1 + name: 'PCI bridge: Intel Corporation Atom Processor C3000 Series Integrated LAN + Root Port #0 (rev 11)' +- bus: '00' + dev: '18' + fn: '0' + id: 19d3 + name: 'Communication controller: Intel Corporation Atom Processor C3000 Series ME + HECI 1 (rev 11)' +- bus: '00' + dev: 1a + fn: '0' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1a + fn: '1' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1a + fn: '2' + id: 19d8 + name: 'Serial controller: Intel Corporation Atom Processor C3000 Series HSUART Controller + (rev 11)' +- bus: '00' + dev: 1c + fn: '0' + id: 19db + name: 'SD Host controller: Intel Corporation Device 19db (rev 11)' +- bus: '00' + dev: 1f + fn: '0' + id: 19dc + name: 'ISA bridge: Intel Corporation Atom Processor C3000 Series LPC or eSPI (rev + 11)' +- bus: '00' + dev: 1f + fn: '2' + id: 19de + name: 'Memory controller: Intel Corporation Atom Processor C3000 Series Power Management + Controller (rev 11)' +- bus: '00' + dev: 1f + fn: '4' + id: 19df + name: 'SMBus: Intel Corporation Atom Processor C3000 Series SMBus controller (rev + 11)' +- bus: '00' + dev: 1f + fn: '5' + id: 19e0 + name: 'Serial bus controller [0c80]: Intel Corporation Atom Processor C3000 Series + SPI Controller (rev 11)' +- bus: '01' + dev: '00' + fn: '0' + id: 19e2 + name: 'Co-processor: Intel Corporation Atom Processor C3000 Series QuickAssist Technology + (rev 11)' +- bus: '02' + dev: '00' + fn: '0' + id: b870 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b870 (rev 01)' +- bus: '03' + dev: '00' + fn: '0' + id: '7021' + name: 'Memory controller: Xilinx Corporation Device 7021' +- bus: '04' + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: '05' + dev: '00' + fn: '0' + id: 15c2 + name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane + (rev 11)' +- bus: '05' + dev: '00' + fn: '1' + id: 15c2 + name: 'Ethernet controller: Intel Corporation Ethernet Connection X553 Backplane + (rev 11)' diff --git a/device/celestica/x86_64-cel_seastone_2-r0/platform.json b/device/celestica/x86_64-cel_seastone_2-r0/platform.json new file mode 100644 index 0000000000..9d2b5841f1 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/platform.json @@ -0,0 +1,235 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1", + "lanes": "1,2,3,4", + "breakout_modes": { + "1x100G": ["Eth1/1"] + } + }, + "Ethernet4": { + "index": "2,2,2,2", + "lanes": "5,6,7,8", + "breakout_modes": { + "1x100G": ["Eth2/1"] + } + }, + "Ethernet8": { + "index": "3,3,3,3", + "lanes": "9,10,11,12", + "breakout_modes": { + "1x100G": ["Eth3/1"] + } + }, + "Ethernet12": { + "index": "4,4,4,4", + "lanes": "13,14,15,16", + "breakout_modes": { + "1x100G": ["Eth4/1"] + } + }, + "Ethernet16": { + "index": "5,5,5,5", + "lanes": "17,18,19,20", + "breakout_modes": { + "1x100G": ["Eth5/1"] + } + }, + "Ethernet20": { + "index": "6,6,6,6", + "lanes": "21,22,23,24", + "breakout_modes": { + "1x100G": ["Eth6/1"] + } + }, + "Ethernet24": { + "index": "7,7,7,7", + "lanes": "25,26,27,28", + "breakout_modes": { + "1x100G": ["Eth7/1"] + } + }, + "Ethernet28": { + "index": "8,8,8,8", + "lanes": "29,30,31,32", + "breakout_modes": { + "1x100G": ["Eth8/1"] + } + }, + "Ethernet32": { + "index": "9,9,9,9", + "lanes": "33,34,35,36", + "breakout_modes": { + "1x100G": ["Eth9/1"] + } + }, + "Ethernet36": { + "index": "10,10,10,10", + "lanes": "37,38,39,40", + "breakout_modes": { + "1x100G": ["Eth10/1"] + } + }, + "Ethernet40": { + "index": "11,11,11,11", + "lanes": "41,42,43,44", + "breakout_modes": { + "1x100G": ["Eth11/1"] + } + }, + "Ethernet44": { + "index": "12,12,12,12", + "lanes": "45,46,47,48", + "breakout_modes": { + "1x100G": ["Eth12/1"] + } + }, + "Ethernet48": { + "index": "13,13,13,13", + "lanes": "49,50,51,52", + "breakout_modes": { + "1x100G": ["Eth13/1"] + } + }, + "Ethernet52": { + "index": "14,14,14,14", + "lanes": "53,54,55,56", + "breakout_modes": { + "1x100G": ["Eth14/1"] + } + }, + "Ethernet56": { + "index": "15,15,15,15", + "lanes": "57,58,59,60", + "breakout_modes": { + "1x100G": ["Eth15/1"] + } + }, + "Ethernet60": { + "index": "16,16,16,16", + "lanes": "61,62,63,64", + "breakout_modes": { + "1x100G": ["Eth16/1"] + } + }, + "Ethernet64": { + "index": "17,17,17,17", + "lanes": "65,66,67,68", + "breakout_modes": { + "1x100G": ["Eth17/1"] + } + }, + "Ethernet68": { + "index": "18,18,18,18", + "lanes": "69,70,71,72", + "breakout_modes": { + "1x100G": ["Eth18/1"] + } + }, + "Ethernet72": { + "index": "19,19,19,19", + "lanes": "73,74,75,76", + "breakout_modes": { + "1x100G": ["Eth19/1"] + } + }, + "Ethernet76": { + "index": "20,20,20,20", + "lanes": "77,78,79,80", + "breakout_modes": { + "1x100G": ["Eth20/1"] + } + }, + "Ethernet80": { + "index": "21,21,21,21", + "lanes": "81,82,83,84", + "breakout_modes": { + "1x100G": ["Eth21/1"] + } + }, + "Ethernet84": { + "index": "22,22,22,22", + "lanes": "85,86,87,88", + "breakout_modes": { + "1x100G": ["Eth22/1"] + } + }, + "Ethernet88": { + "index": "23,23,23,23", + "lanes": "89,90,91,92", + "breakout_modes": { + "1x100G": ["Eth23/1"] + } + }, + "Ethernet92": { + "index": "24,24,24,24", + "lanes": "93,94,95,96", + "breakout_modes": { + "1x100G": ["Eth24/1"] + } + }, + "Ethernet96": { + "index": "25,25,25,25", + "lanes": "97,98,99,100", + "breakout_modes": { + "1x100G": ["Eth25/1"] + } + }, + "Ethernet100": { + "index": "26,26,26,26", + "lanes": "101,102,103,104", + "breakout_modes": { + "1x100G": ["Eth26/1"] + } + }, + "Ethernet104": { + "index": "27,27,27,27", + "lanes": "105,106,107,108", + "breakout_modes": { + "1x100G": ["Eth27/1"] + } + }, + "Ethernet108": { + "index": "28,28,28,28", + "lanes": "109,110,111,112", + "breakout_modes": { + "1x100G": ["Eth28/1"] + } + }, + "Ethernet112": { + "index": "29,29,29,29", + "lanes": "113,114,115,116", + "breakout_modes": { + "1x100G": ["Eth29/1"] + } + }, + "Ethernet116": { + "index": "30,30,30,30", + "lanes": "117,118,119,120", + "breakout_modes": { + "1x100G": ["Eth30/1"] + } + }, + "Ethernet120": { + "index": "31,31,31,31", + "lanes": "121,122,123,124", + "breakout_modes": { + "1x100G": ["Eth31/1"] + } + }, + "Ethernet124": { + "index": "32,32,32,32", + "lanes": "125,126,127,128", + "breakout_modes": { + "1x100G": ["Eth32/1"] + } + }, + "Ethernet128": { + "index": "33", + "lanes": "129", + "breakout_modes": { + "1x10G": ["Eth33/1"] + } + } + } +} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/platform_components.json b/device/celestica/x86_64-cel_seastone_2-r0/platform_components.json new file mode 100644 index 0000000000..7daf37202c --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/platform_components.json @@ -0,0 +1,17 @@ +{ + "chassis": { + "Seastone_2": { + "component": { + "BIOS": {}, + "ONIE": {}, + "BMC": {}, + "FPGA": {}, + "CPLD COMe": {}, + "CPLD BASE": {}, + "CPLD SW1": {}, + "CPLD SW2": {}, + "SSD": {} + } + } + } +} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/platform_reboot b/device/celestica/x86_64-cel_seastone_2-r0/platform_reboot new file mode 100755 index 0000000000..be80ddbdd1 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/platform_reboot @@ -0,0 +1,6 @@ +#!/bin/bash + +# Set all LEDs to BMC's control +ipmitool raw 0x3a 0x0f 0x02 0x01 &> /dev/null + +/usr/local/bin/seastone2_platform_shutdown.sh system diff --git a/device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py index 2eb92eb919..cc5461ccb5 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_seastone_2-r0/plugins/psuutil.py @@ -1,9 +1,10 @@ +import os.path +import subprocess import sys import re try: from sonic_psu.psu_base import PsuBase - from sonic_py_common.general import getstatusoutput_noshell_pipe except ImportError as e: raise ImportError(str(e) + "- required module not found") @@ -12,16 +13,16 @@ class PsuUtil(PsuBase): """Platform-specific PSUutil class""" def __init__(self): - self.ipmi_sensor = ["ipmitool", "sensor"] + self.ipmi_sensor = "ipmitool sensor" PsuBase.__init__(self) - def run_command(self, cmd1, cmd2): - exitcode, out = getstatusoutput_noshell_pipe(cmd1, cmd2) - i = 0 - while i < 2: - if exitcode[i] != 0: - sys.exit(exitcode[i]) - i += 1 + def run_command(self, command): + proc = subprocess.Popen(command, shell=True, universal_newlines=True, stdout=subprocess.PIPE) + (out, err) = proc.communicate() + + if proc.returncode != 0: + sys.exit(proc.returncode) + return out def find_value(self, grep_string): @@ -49,8 +50,7 @@ class PsuUtil(PsuBase): return False grep_key = "PSUL_Status" if index == 1 else "PSUR_Status" - grep_cmd = ["grep", grep_key] - grep_string = self.run_command(self.ipmi_sensor, grep_cmd) + grep_string = self.run_command(self.ipmi_sensor + ' | grep ' + grep_key) status_byte = self.find_value(grep_string) if status_byte is None: @@ -74,8 +74,7 @@ class PsuUtil(PsuBase): return False grep_key = "PSUL_Status" if index == 1 else "PSUR_Status" - grep_cmd = ["grep", grep_key] - grep_string = self.run_command(self.ipmi_sensor, grep_cmd) + grep_string = self.run_command(self.ipmi_sensor + ' | grep ' + grep_key) status_byte = self.find_value(grep_string) if status_byte is None: diff --git a/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json index 5e59513ef6..f5b2736b13 100644 --- a/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json +++ b/device/celestica/x86_64-cel_seastone_2-r0/pmon_daemon_control.json @@ -1,7 +1,5 @@ { "skip_ledd": true, - "skip_xcvrd": false, - "skip_psud": false, - "skip_syseepromd": false, - "skip_fancontrol": true -} \ No newline at end of file + "skip_fancontrol": true, + "skip_xcvrd_cmis_mgr": true +} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json deleted file mode 100644 index dfa1a1bddf..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/chassis.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - "eeprom": "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom", - "get_reboot_cause": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x06", - "output_translator": { - "00": "Hardware - Other", - "11": "Hardware - Other", - "22": "Non-Hardware", - "33": "Hardware - Other", - "44": "Non-Hardware", - "55": "Non-Hardware", - "77": "Watchdog", - "88": "Thermal Overload: CPU", - "99": "Thermal Overload: ASIC" - } - }, - "get_reboot_description": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x06", - "output_translator": { - "00": "The last reset is power cycle reset (set register 0xA164)", - "11": "The last reset is Power on reset", - "22": "The last reset is soft-set CPU warm reset", - "33": "The last reset is soft-set CPU cold reset", - "44": "The last reset is CPU warm reset", - "55": "The last reset is CPU cold reset", - "77": "The last reset is watchdog reset", - "88": "The last reset is CPU thermal overload", - "99": "The last reset is ASIC thermal overload" - } - }, - "get_watchdog": { - "output_source": "class", - "host_path": "/usr/share/sonic/device/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py", - "pmon_path": "/usr/share/sonic/platform/sonic_platform_config/watchdog.py", - "class": "Watchdog" - }, - "get_change_event": { - "output_source": "class", - "host_path": "/usr/share/sonic/device/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py", - "pmon_path": "/usr/share/sonic/platform/sonic_platform_config/event.py", - "class": "SfpEvent" - } -} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json deleted file mode 100644 index 96f646206f..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/component.json +++ /dev/null @@ -1,62 +0,0 @@ -{ - "component_num": 5, - "get_name": { - "output_source": "value_list", - "value_list": [ - "BIOS", - "CPLD_BASEBOARD", - "CPLD_SWITCHBOARD", - "FPGA", - "BMC" - ] - }, - "get_description": { - "output_source": "value_list", - "value_list": [ - "Used to perform hardware initialization during the booting process", - "Used to control the system power & reset, Control FAN, UART Mux etc", - "Used for managing QSFP ports", - "Used for managing I2C, SPI, PCIe etc", - "Used for monitoring and managing whole system" - ] - }, - "get_firmware_version": { - "output_source": "function", - "function": [ - "_get_bios_ver", - "_get_base_cpld_ver", - "_get_sw_cpld_ver", - "_get_fpga_ver", - "_get_bmc_ver" - ] - }, - "_get_bmc_ver": { - "output_source": "ipmitool", - "command": "ipmitool mc info | grep 'Firmware Revision'", - "output_translator": "'{}'.split(':')[-1].strip()" - }, - "_get_bios_ver": { - "output_source": "txt_file", - "path": "/sys/class/dmi/id/bios_version" - }, - "_get_base_cpld_ver": { - "output_source": "hex_version_file", - "num_of_points": 1, - "num_of_bits": 8, - "path": "/sys/devices/platform/baseboard/version" - }, - "_get_sw_cpld_ver": { - "output_source": "hex_version_getreg", - "num_of_points": 1, - "num_of_bits": 8, - "reg_addr": "0x00", - "path": "/sys/devices/platform/switchboard/CPLD1/getreg" - }, - "_get_fpga_ver": { - "output_source": "hex_version_getreg", - "num_of_points": 1, - "num_of_bits": 32, - "reg_addr": "0x00", - "path": "/sys/devices/platform/switchboard/FPGA/getreg" - } -} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py deleted file mode 100644 index 32073479a1..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/event.py +++ /dev/null @@ -1,117 +0,0 @@ -############################################################################# -# Celestica Seastone2 -# -# SfpEvent contains an implementation of SONiC Platform Base API -# -############################################################################# -try: - import time - import os - from sonic_platform.common import Common -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - -PLATFORM_PATH = "/sys/devices/platform/" -SWITCH_BRD_PLATFORM = "switchboard" -POLL_INTERVAL = 1 - - -class SfpEvent: - ''' Listen to insert/remove sfp events ''' - - PORT_INFO_DIR = 'SFF' - PATH_INT_SYSFS = "{0}/{port_name}/{type_prefix}_isr_flags" - PATH_INTMASK_SYSFS = "{0}/{port_name}/{type_prefix}_isr_mask" - PATH_PRS_SYSFS = "{0}/{port_name}/{prs_file_name}" - PRESENT_EN = 0x01 - - def __init__(self, sfp_list): - self.num_sfp = len(sfp_list) - self._api_common = Common() - self._initialize_interrupts() - - def _initialize_interrupts(self): - sfp_info_obj = {} - port_info_path = os.path.join( - PLATFORM_PATH, SWITCH_BRD_PLATFORM, self.PORT_INFO_DIR) - - for index in range(self.num_sfp): - port_num = index + 1 - if port_num <= 32: - port_name = "QSFP{}".format(port_num) - port_type = "qsfp" - sysfs_prs_file = "{}_modprs".format(port_type) - else: - port_name = "SFP{}".format(port_num - 32) - port_type = "sfp" - sysfs_prs_file = "{}_modabs".format(port_type) - - sfp_info_obj[index] = {} - sfp_info_obj[index]['intmask_sysfs'] = self.PATH_INTMASK_SYSFS.format( - port_info_path, - port_name=port_name, - type_prefix=port_type) - - sfp_info_obj[index]['int_sysfs'] = self.PATH_INT_SYSFS.format( - port_info_path, - port_name=port_name, - type_prefix=port_type) - - sfp_info_obj[index]['prs_sysfs'] = self.PATH_PRS_SYSFS.format( - port_info_path, - port_name=port_name, - prs_file_name=sysfs_prs_file) - - self._api_common.write_txt_file( - sfp_info_obj[index]["intmask_sysfs"], hex(self.PRESENT_EN)) - - self.sfp_info_obj = sfp_info_obj - - def _is_port_device_present(self, port_idx): - prs_path = self.sfp_info_obj[port_idx]["prs_sysfs"] - is_present = 1 - int(self._api_common.read_txt_file(prs_path)) - return is_present - - def _update_port_event_object(self, interrup_devices, port_dict): - for port_idx in interrup_devices: - device_id = str(port_idx + 1) - port_dict[device_id] = str(self._is_port_device_present(port_idx)) - return port_dict - - def _clear_event_flag(self, path): - self._api_common.write_txt_file(path, hex(0xff)) - time.sleep(0.1) - self._api_common.write_txt_file(path, hex(0x0)) - - def _check_all_port_interrupt_event(self): - interrupt_devices = {} - for i in range(self.num_sfp): - int_sysfs = self.sfp_info_obj[i]["int_sysfs"] - interrupt_flags = self._api_common.read_txt_file(int_sysfs) - if interrupt_flags != '0x00': - interrupt_devices[i] = 1 - self._clear_event_flag(int_sysfs) - return interrupt_devices - - def get_event(self, timeout): - sleep_time = min( - timeout, POLL_INTERVAL) if timeout != 0 else POLL_INTERVAL - start_milli_time = int(round(time.time() * 1000)) - int_sfp = {} - - while True: - chk_sfp = self._check_all_port_interrupt_event() - int_sfp = self._update_port_event_object( - chk_sfp, int_sfp) if chk_sfp else int_sfp - current_milli_time = int(round(time.time() * 1000)) - if (int_sfp) or \ - (timeout != 0 and current_milli_time - start_milli_time > timeout): - break - - time.sleep(sleep_time) - - change_dict = dict() - change_dict['sfp'] = int_sfp - - return True, change_dict diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json deleted file mode 100644 index 724f6edf53..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/fan.json +++ /dev/null @@ -1,200 +0,0 @@ -{ - "fan_num_per_drawer": 2, - "drawer_num": 4, - "get_name": { - "output_source": "value_list", - "value_list": [ - "Fan1-F", - "Fan1-R", - "Fan2-F", - "Fan2-R", - "Fan3-F", - "Fan3-R", - "Fan4-F", - "Fan4-R" - ] - }, - "get_presence": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x3a 0x03 0x03 {}", - "argument": [ - "0x00", - "0x00", - "0x01", - "0x01", - "0x02", - "0x02", - "0x03", - "0x03" - ], - "output_translator": "True if '00' in '{}' else False" - }, - "get_model": { - "output_source": "ipmitool", - "command": "ipmitool fru list {} | grep 'Board Part Number'", - "argument": [ - "5", - "5", - "6", - "6", - "7", - "7", - "8", - "8" - ], - "output_translator": "'{}'.split()[-1]" - }, - "get_serial": { - "output_source": "ipmitool", - "command": "ipmitool fru list {} | grep 'Board Serial'", - "argument": [ - "5", - "5", - "6", - "6", - "7", - "7", - "8", - "8" - ], - "output_translator": "'{}'.split()[-1]" - }, - "get_direction": { - "output_source": "ipmitool", - "command": "ipmitool fru list {} | grep 'F2B\\|B2F'", - "argument": [ - "5", - "5", - "6", - "6", - "7", - "7", - "8", - "8" - ], - "output_translator": "'intake' if 'B2F' in '{}' else 'exhaust'" - }, - "get_speed": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x04 0x2d {}", - "argument": [ - "0x81", - "0x80", - "0x83", - "0x82", - "0x85", - "0x84", - "0x87", - "0x86" - ], - "output_translator": "int('{}'.split()[0],16)*150", - "max_front": 23000, - "max_rear": 20500 - }, - "get_target_speed": { - "output_source": "value", - "value": "N/A" - }, - "get_speed_tolerance": { - "output_source": "value", - "value": 10 - }, - "set_speed": { - "set_method": "ipmitool", - "input_translator": "hex(int({} * 255 / 100.0))", - "command": "ipmitool raw 0x3a 0x0c 0x00 0x03 {}", - "argument": [ - "0x40 {}", - "0x40 {}", - "0x44 {}", - "0x44 {}", - "0x4c {}", - "0x4c {}", - "0x50 {}", - "0x50 {}" - ] - }, - "set_status_led": { - "set_method": "ipmitool", - "avaliable_input": [ - "off", - "amber", - "green" - ], - "input_translator": { - "off": "0x0", - "amber": "0x1", - "green": "0x2" - }, - "command": "ipmitool raw 0x3a 0x0a {}", - "argument": [ - "0x4 {}", - "0x4 {}", - "0x5 {}", - "0x5 {}", - "0x6 {}", - "0x6 {}", - "0x7 {}", - "0x7 {}" - ] - }, - "get_status_led": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x3a 0x0b {}", - "argument": [ - "0x4", - "0x4", - "0x5", - "0x5", - "0x6", - "0x6", - "0x7", - "0x7" - ], - "output_translator": { - "00": "off", - "01": "amber", - "02": "green" - } - }, - "psu_fan": [ - { - "num_of_fan": 1, - "get_name": { - "output_source": "value_list", - "value_list": [ - "PSU-R-Fan" - ] - }, - "get_speed": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x04 0x2d {}", - "argument": [ - "0x8b" - ], - "output_translator": "int('{}'.split()[0],16)*100", - "max_front": 22600, - "max_rear": 22600 - } - }, - { - "num_of_fan": 1, - "get_name": { - "output_source": "value_list", - "value_list": [ - "PSU-L-Fan" - ] - }, - "get_speed": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x04 0x2d {}", - "argument": [ - "0x8a" - ], - "output_translator": "int('{}'.split()[0],16)*100", - "max_front": 22600, - "max_rear": 22600 - } - } - ] -} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json deleted file mode 100644 index c3e953c082..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/psu.json +++ /dev/null @@ -1,135 +0,0 @@ -{ - "psu_num": 2, - "fan_per_psu_num": 1, - "get_name": { - "output_source": "value_list", - "value_list": [ - "PSU-R", - "PSU-L" - ] - }, - "get_power": { - "output_source": "ipmitool", - "command": "ipmitool sdr | grep {}", - "argument": [ - "PSUR_POut", - "PSUL_POut" - ], - "output_translator": "float('{}'.split()[2])" - }, - "get_current": { - "output_source": "ipmitool", - "command": "ipmitool sdr | grep {}", - "argument": [ - "PSUR_COut", - "PSUL_COut" - ], - "output_translator": "float('{}'.split()[2])" - }, - "get_voltage": { - "output_source": "ipmitool", - "command": "ipmitool sdr | grep {}", - "argument": [ - "PSUR_VOut", - "PSUL_VOut" - ], - "output_translator": "float('{}'.split()[2])" - }, - "get_voltage_high_threshold": { - "output_source": "ipmitool", - "command": "ipmitool sensor list | grep {}", - "argument": [ - "PSUR_Temp2", - "PSUL_Temp2" - ], - "output_translator": "float(0 if '{0}'.split()[-3]=='na' else '{0}'.split()[-3])" - }, - "get_voltage_low_threshold": { - "output_source": "ipmitool", - "command": "ipmitool sensor list | grep {}", - "argument": [ - "PSUR_Temp2", - "PSUL_Temp2" - ], - "output_translator": "float(0 if '{0}'.split()[-9]=='na' else '{0}'.split()[-9])" - }, - "get_presence": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x3a 0x0c 0x00 0x2 0x60", - "output_translator": [ - "True if (int('{}', 16) >> 4 & 1) == 0 else False", - "True if (int('{}', 16) >> 5 & 1) == 0 else False" - ] - }, - "get_model": { - "output_source": "ipmitool", - "command": "ipmitool fru list {} | grep 'Product Part Number'", - "argument": [ - "4", - "3" - ], - "output_translator": "'{}'.split()[-1]" - }, - "get_serial": { - "output_source": "ipmitool", - "command": "ipmitool fru list {} | grep 'Product Serial'", - "argument": [ - "4", - "3" - ], - "output_translator": "'{}'.split()[-1]" - }, - "get_powergood_status": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x3a 0x0c 0x0 0x2 0x60", - "output_translator": [ - "True if (int('{}', 16) >> 2 & 1) == 1 else False", - "True if (int('{}', 16) >> 3 & 1) == 1 else False" - ] - }, - "set_status_led": { - "set_method": "ipmitool", - "avaliable_input": [ - "amber" - ], - "input_translator": { - "amber": "0x1" - }, - "command": "ipmitool raw 0x3a 0x0a {}", - "argument": [ - "0x3 {}", - "0x2 {}" - ] - }, - "get_status_led": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x3a 0x0b {}", - "argument": [ - "0x3", - "0x2" - ], - "output_translator": { - "00": "green", - "01": "amber" - }, - "default_output": "off" - }, - "get_temperature": { - "output_source": "ipmitool", - "command": "ipmitool sdr | grep {}", - "argument": [ - "PSUR_Temp2", - "PSUL_Temp2" - ], - "output_translator": "float('{}'.split()[2])" - }, - "get_temperature_high_threshold": { - "output_source": "ipmitool", - "command": "ipmitool sensor list | grep {}", - "argument": [ - "PSUR_Temp2", - "PSUL_Temp2" - ], - "output_translator": "float(0 if '{0}'.split()[-3]=='na' else '{0}'.split()[-3])" - } -} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json deleted file mode 100644 index d12f0c3ffc..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/sfp.json +++ /dev/null @@ -1,143 +0,0 @@ -{ - "port_num": 33, - "eeprom_path": "/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom", - "port_i2c_mapping": [ - 2, - 3, - 4, - 5, - 6, - 7, - 8, - 9, - 10, - 11, - 12, - 13, - 14, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34 - ], - "get_presence": { - "output_source": "sysfs_value", - "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}", - "argument": "$ref:_presence_file", - "output_translator": "False if '{}' == '1' else True" - }, - "get_lpmode": { - "output_source": "sysfs_value", - "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_lpmode", - "argument": "$ref:_port_name", - "output_translator": "True if '{}' == '1' else False" - }, - "get_reset_status": { - "output_source": "sysfs_value", - "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_reset", - "argument": "$ref:_port_name", - "output_translator": "False if '{}' == '1' else True" - }, - "reset": { - "set_method": "sysfs_value", - "write_offset": 0, - "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_reset", - "argument": "$ref:_port_name" - }, - "set_lpmode": { - "set_method": "sysfs_value", - "input_translator": { - "True": "0x1", - "False": "0x0" - }, - "write_offset": 0, - "sysfs_path": "/sys/devices/platform/switchboard/SFF/{}/qsfp_lpmode", - "argument": "$ref:_port_name" - }, - "_port_name": [ - "QSFP1", - "QSFP2", - "QSFP3", - "QSFP4", - "QSFP5", - "QSFP6", - "QSFP7", - "QSFP8", - "QSFP9", - "QSFP10", - "QSFP11", - "QSFP12", - "QSFP13", - "QSFP14", - "QSFP15", - "QSFP16", - "QSFP17", - "QSFP18", - "QSFP19", - "QSFP20", - "QSFP21", - "QSFP22", - "QSFP23", - "QSFP24", - "QSFP25", - "QSFP26", - "QSFP27", - "QSFP28", - "QSFP29", - "QSFP30", - "QSFP31", - "QSFP32", - "SFP1" - ], - "_presence_file": [ - "QSFP1/qsfp_modprs", - "QSFP2/qsfp_modprs", - "QSFP3/qsfp_modprs", - "QSFP4/qsfp_modprs", - "QSFP5/qsfp_modprs", - "QSFP6/qsfp_modprs", - "QSFP7/qsfp_modprs", - "QSFP8/qsfp_modprs", - "QSFP9/qsfp_modprs", - "QSFP10/qsfp_modprs", - "QSFP11/qsfp_modprs", - "QSFP12/qsfp_modprs", - "QSFP13/qsfp_modprs", - "QSFP14/qsfp_modprs", - "QSFP15/qsfp_modprs", - "QSFP16/qsfp_modprs", - "QSFP17/qsfp_modprs", - "QSFP18/qsfp_modprs", - "QSFP19/qsfp_modprs", - "QSFP20/qsfp_modprs", - "QSFP21/qsfp_modprs", - "QSFP22/qsfp_modprs", - "QSFP23/qsfp_modprs", - "QSFP24/qsfp_modprs", - "QSFP25/qsfp_modprs", - "QSFP26/qsfp_modprs", - "QSFP27/qsfp_modprs", - "QSFP28/qsfp_modprs", - "QSFP29/qsfp_modprs", - "QSFP30/qsfp_modprs", - "QSFP31/qsfp_modprs", - "QSFP32/qsfp_modprs", - "SFP1/sfp_modabs" - ] -} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json deleted file mode 100644 index e3dcb7fb92..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/thermal.json +++ /dev/null @@ -1,105 +0,0 @@ -{ - "thermal_num": 9, - "get_name": { - "output_source": "value_list", - "value_list": [ - "Base_Temp_U5", - "Base_Temp_U7", - "CPU_Temp", - "Switch_Temp_U1", - "Switch_Temp_U18", - "Switch_Temp_U28", - "Switch_Temp_U29", - "Switch_U21_Temp", - "Switch_U33_Temp" - ] - }, - "get_temperature": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x04 0x2D {}", - "argument": [ - "0x1", - "0x2", - "0x7", - "0x3", - "0x4", - "0x5", - "0x6", - "0x56", - "0x4C" - ], - "output_translator": "int('{}'.split()[0],16)" - }, - "get_high_threshold": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x04 0x27 {}", - "argument": [ - "0x1", - "0x2", - "0x7", - "0x3", - "0x4", - "0x5", - "0x6", - "0x56", - "0x4c" - ], - "output_translator": "int('{}'.split()[4], 16)" - }, - "get_low_threshold": { - "output_source": "value", - "value": "N/A" - }, - "set_high_threshold": { - "set_method": "ipmitool", - "command": "ipmitool sensor thresh {}", - "input_translator": "{}", - "argument": [ - "Base_Temp_U5 unc {}", - "Base_Temp_U7 unc {}", - "CPU_Temp unc {}", - "Switch_Temp_U1 unc {}", - "Switch_Temp_U18 unc {}", - "Switch_Temp_U28 unc {}", - "Switch_Temp_U29 unc {}", - "Switch_U21_Temp unc {}", - "Switch_U33_Temp unc {}" - ] - }, - "set_low_threshold": { - "output_source": "ipmitool", - "command": "ipmitool sensor thresh {}", - "input_translator": "{}", - "argument": [ - "Base_Temp_U5 lnc {}", - "Base_Temp_U7 lnc {}", - "CPU_Temp lnc {}", - "Switch_Temp_U1 lnc {}", - "Switch_Temp_U18 lnc {}", - "Switch_Temp_U28 lnc {}", - "Switch_Temp_U29 lnc {}", - "Switch_U21_Temp lnc {}", - "Switch_U33_Temp lnc {}" - ] - }, - "get_high_critical_threshold": { - "output_source": "ipmitool", - "command": "ipmitool raw 0x04 0x27 {}", - "argument": [ - "0x1", - "0x2", - "0x7", - "0x3", - "0x4", - "0x5", - "0x6", - "0x56", - "0x4c" - ], - "output_translator": "int('{}'.split()[5], 16)" - }, - "get_low_critical_threshold": { - "output_source": "value", - "value": "N/A" - } -} \ No newline at end of file diff --git a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py b/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py deleted file mode 100644 index fac5c40e13..0000000000 --- a/device/celestica/x86_64-cel_seastone_2-r0/sonic_platform_config/watchdog.py +++ /dev/null @@ -1,191 +0,0 @@ -############################################################################# -# Celestica Seastone2 -# -# Watchdog contains an implementation of SONiC Platform Base API -# -############################################################################# -import os -import time - -try: - from sonic_platform_base.watchdog_base import WatchdogBase - from sonic_platform.common import Common -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -PLATFORM_CPLD_PATH = '/sys/devices/platform/baseboard/' -GETREG_FILE = 'getreg' -SETREG_FILE = 'setreg' -WDT_ENABLE_REG = '0xA181' -WDT_TIMER_L_BIT_REG = '0xA182' -WDT_TIMER_M_BIT_REG = '0xA183' -WDT_TIMER_H_BIT_REG = '0xA184' -WDT_KEEP_ALVIVE_REG = '0xA185' -ENABLE_CMD = '0x1' -DISABLE_CMD = '0x0' -WDT_COMMON_ERROR = -1 - - -class Watchdog(WatchdogBase): - - def __init__(self): - WatchdogBase.__init__(self) - - self._api_common = Common() - - # Init cpld reg path - self.setreg_path = os.path.join(PLATFORM_CPLD_PATH, SETREG_FILE) - self.getreg_path = os.path.join(PLATFORM_CPLD_PATH, GETREG_FILE) - - # Set default value - self._disable() - self.armed = False - self.timeout = self._gettimeout() - - def _enable(self): - """ - Turn on the watchdog timer - """ - # echo 0xA181 0x1 > /sys/devices/platform/baseboard/setreg - enable_val = '{} {}'.format(WDT_ENABLE_REG, ENABLE_CMD) - return self._api_common.write_txt_file(self.setreg_path, enable_val) - - def _disable(self): - """ - Turn off the watchdog timer - """ - # echo 0xA181 0x0 > /sys/devices/platform/baseboard/setreg - disable_val = '{} {}'.format(WDT_ENABLE_REG, DISABLE_CMD) - return self._api_common.write_txt_file(self.setreg_path, disable_val) - - def _keepalive(self): - """ - Keep alive watchdog timer - """ - # echo 0xA185 0x1 > /sys/devices/platform/baseboard/setreg - enable_val = '{} {}'.format(WDT_KEEP_ALVIVE_REG, ENABLE_CMD) - return self._api_common.write_txt_file(self.setreg_path, enable_val) - - def _get_level_hex(self, sub_hex): - sub_hex_str = sub_hex.replace("x", "0") - return hex(int(sub_hex_str, 16)) - - def _seconds_to_lmh_hex(self, seconds): - ms = seconds*1000 # calculate timeout in ms format - hex_str = hex(ms) - l = self._get_level_hex(hex_str[-2:]) - m = self._get_level_hex(hex_str[-4:-2]) - h = self._get_level_hex(hex_str[-6:-4]) - return (l, m, h) - - def _settimeout(self, seconds): - """ - Set watchdog timer timeout - @param seconds - timeout in seconds - @return is the actual set timeout - """ - # max = 0xffffff = 16777.215 seconds - - (l, m, h) = self._seconds_to_lmh_hex(seconds) - set_h_val = '{} {}'.format(WDT_TIMER_H_BIT_REG, h) - set_m_val = '{} {}'.format(WDT_TIMER_M_BIT_REG, m) - set_l_val = '{} {}'.format(WDT_TIMER_L_BIT_REG, l) - - self._api_common.write_txt_file( - self.setreg_path, set_h_val) # set high bit - self._api_common.write_txt_file( - self.setreg_path, set_m_val) # set med bit - self._api_common.write_txt_file( - self.setreg_path, set_l_val) # set low bit - - return seconds - - def _gettimeout(self): - """ - Get watchdog timeout - @return watchdog timeout - """ - - h_bit = self._api_common.get_reg( - self.getreg_path, WDT_TIMER_H_BIT_REG) - m_bit = self._api_common.get_reg( - self.getreg_path, WDT_TIMER_M_BIT_REG) - l_bit = self._api_common.get_reg( - self.getreg_path, WDT_TIMER_L_BIT_REG) - - hex_time = '0x{}{}{}'.format(h_bit[2:], m_bit[2:], l_bit[2:]) - ms = int(hex_time, 16) - return int(float(ms)/1000) - - ################################################################# - - def arm(self, seconds): - """ - Arm the hardware watchdog with a timeout of seconds. - If the watchdog is currently armed, calling this function will - simply reset the timer to the provided value. If the underlying - hardware does not support the value provided in , this - method should arm the watchdog with the *next greater* available - value. - Returns: - An integer specifying the *actual* number of seconds the watchdog - was armed with. On failure returns -1. - """ - - ret = WDT_COMMON_ERROR - if seconds < 0: - return ret - - try: - if self.timeout != seconds: - self.timeout = self._settimeout(seconds) - - if self.armed: - self._keepalive() - else: - self._enable() - self.armed = True - - ret = self.timeout - self.arm_timestamp = time.time() - except IOError as e: - pass - - return ret - - def disarm(self): - """ - Disarm the hardware watchdog - Returns: - A boolean, True if watchdog is disarmed successfully, False if not - """ - disarmed = False - if self.is_armed(): - try: - self._disable() - self.armed = False - disarmed = True - except IOError: - pass - - return disarmed - - def is_armed(self): - """ - Retrieves the armed state of the hardware watchdog. - Returns: - A boolean, True if watchdog is armed, False if not - """ - - return self.armed - - def get_remaining_time(self): - """ - If the watchdog is armed, retrieve the number of seconds remaining on - the watchdog timer - Returns: - An integer specifying the number of seconds remaining on thei - watchdog timer. If the watchdog is not armed, returns -1. - """ - - return int(self.timeout - (time.time() - self.arm_timestamp)) if self.armed else WDT_COMMON_ERROR diff --git a/device/celestica/x86_64-cel_seastone_2-r0/system_health_monitoring_config.json b/device/celestica/x86_64-cel_seastone_2-r0/system_health_monitoring_config.json new file mode 100644 index 0000000000..56fda7de4f --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/system_health_monitoring_config.json @@ -0,0 +1,13 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "psu.temperature" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "amber", + "normal": "green", + "booting": "green_blink_1hz" + } +} diff --git a/device/celestica/x86_64-cel_seastone_2-r0/warm-reboot_plugin b/device/celestica/x86_64-cel_seastone_2-r0/warm-reboot_plugin new file mode 100755 index 0000000000..d0fb8b29e1 --- /dev/null +++ b/device/celestica/x86_64-cel_seastone_2-r0/warm-reboot_plugin @@ -0,0 +1,4 @@ +#!/bin/bash + +# Set all LEDs to BMC's control +ipmitool raw 0x3a 0x0f 0x02 0x01 &> /dev/null diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm index 447de2e85b..44d9f697d9 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone-128x100/th3-128x100G.config.bcm @@ -9,10 +9,6 @@ phy_enable=0 phy_null=1 pll_bypass=1 -init_all_modules=0 - -sai_tunnel_global_sip_mask_enable=1 - portmap_20=33:100:2 portmap_21=35:100:2 portmap_22=37:100:2 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/hwsku.json b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/hwsku.json new file mode 100644 index 0000000000..b97d516509 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/hwsku.json @@ -0,0 +1,164 @@ +{ + "interfaces": { + "Ethernet0": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet8": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet16": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet24": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet32": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet40": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet48": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet56": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet64": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet72": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet80": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet88": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet96": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet104": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet112": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet120": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet128": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet136": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet144": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet152": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet160": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet168": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet176": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet184": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet192": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet200": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet208": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet216": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet224": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet232": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet240": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + }, + "Ethernet248": { + "default_brkout_mode": "1x400G", + "autoneg": "off", + "fec": "rs" + } + } +} diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini index 9cd85ee347..1d2b56d9fe 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/port_config.ini @@ -1,33 +1,33 @@ # name lanes alias index speed -Ethernet0 33,34,35,36,37,38,39,40 QSFPDD1 1 400000 -Ethernet4 41,42,43,44,45,46,47,48 QSFPDD2 2 400000 -Ethernet8 49,50,51,52,53,54,55,56 QSFPDD3 3 400000 -Ethernet12 57,58,59,60,61,62,63,64 QSFPDD4 4 400000 -Ethernet16 65,66,67,68,69,70,71,72 QSFPDD5 5 400000 -Ethernet20 73,74,75,76,77,78,79,80 QSFPDD6 6 400000 -Ethernet24 81,82,83,84,85,86,87,88 QSFPDD7 7 400000 -Ethernet28 89,90,91,92,93,94,95,96 QSFPDD8 8 400000 -Ethernet32 1,2,3,4,5,6,7,8 QSFPDD9 9 400000 -Ethernet36 9,10,11,12,13,14,15,16 QSFPDD10 10 400000 -Ethernet40 17,18,19,20,21,22,23,24 QSFPDD11 11 400000 -Ethernet44 25,26,27,28,29,30,31,32 QSFPDD12 12 400000 -Ethernet48 97,98,99,100,101,102,103,104 QSFPDD13 13 400000 -Ethernet52 105,106,107,108,109,110,111,112 QSFPDD14 14 400000 -Ethernet56 113,114,115,116,117,118,119,120 QSFPDD15 15 400000 -Ethernet60 121,122,123,124,125,126,127,128 QSFPDD16 16 400000 -Ethernet64 129,130,131,132,133,134,135,136 QSFPDD17 17 400000 -Ethernet68 137,138,139,140,141,142,143,144 QSFPDD18 18 400000 -Ethernet72 145,146,147,148,149,150,151,152 QSFPDD19 19 400000 -Ethernet76 153,154,155,156,157,158,159,160 QSFPDD20 20 400000 -Ethernet80 225,226,227,228,229,230,231,232 QSFPDD21 21 400000 -Ethernet84 233,234,235,236,237,238,239,240 QSFPDD22 22 400000 -Ethernet88 241,242,243,244,245,246,247,248 QSFPDD23 23 400000 -Ethernet92 249,250,251,252,253,254,255,256 QSFPDD24 24 400000 -Ethernet96 161,162,163,164,165,166,167,168 QSFPDD25 25 400000 -Ethernet100 169,170,171,172,173,174,175,176 QSFPDD26 26 400000 -Ethernet104 177,178,179,180,181,182,183,184 QSFPDD27 27 400000 -Ethernet108 185,186,187,188,189,190,191,192 QSFPDD28 28 400000 -Ethernet112 193,194,195,196,197,198,199,200 QSFPDD29 29 400000 -Ethernet116 201,202,203,204,205,206,207,208 QSFPDD30 30 400000 -Ethernet120 209,210,211,212,213,214,215,216 QSFPDD31 31 400000 -Ethernet124 217,218,219,220,221,222,223,224 QSFPDD32 32 400000 \ No newline at end of file +Ethernet0 33,34,35,36,37,38,39,40 Eth1/1 1 400000 +Ethernet8 41,42,43,44,45,46,47,48 Eth2/1 2 400000 +Ethernet16 49,50,51,52,53,54,55,56 Eth3/1 3 400000 +Ethernet24 57,58,59,60,61,62,63,64 Eth4/1 4 400000 +Ethernet32 65,66,67,68,69,70,71,72 Eth5/1 5 400000 +Ethernet40 73,74,75,76,77,78,79,80 Eth6/1 6 400000 +Ethernet48 81,82,83,84,85,86,87,88 Eth7/1 7 400000 +Ethernet56 89,90,91,92,93,94,95,96 Eth8/1 8 400000 +Ethernet64 1,2,3,4,5,6,7,8 Eth9/1 9 400000 +Ethernet72 9,10,11,12,13,14,15,16 Eth10/1 10 400000 +Ethernet80 17,18,19,20,21,22,23,24 Eth11/1 11 400000 +Ethernet88 25,26,27,28,29,30,31,32 Eth12/1 12 400000 +Ethernet96 97,98,99,100,101,102,103,104 Eth13/1 13 400000 +Ethernet104 105,106,107,108,109,110,111,112 Eth14/1 14 400000 +Ethernet112 113,114,115,116,117,118,119,120 Eth15/1 15 400000 +Ethernet120 121,122,123,124,125,126,127,128 Eth16/1 16 400000 +Ethernet128 129,130,131,132,133,134,135,136 Eth17/1 17 400000 +Ethernet136 137,138,139,140,141,142,143,144 Eth18/1 18 400000 +Ethernet144 145,146,147,148,149,150,151,152 Eth19/1 19 400000 +Ethernet152 153,154,155,156,157,158,159,160 Eth20/1 20 400000 +Ethernet160 225,226,227,228,229,230,231,232 Eth21/1 21 400000 +Ethernet168 233,234,235,236,237,238,239,240 Eth22/1 22 400000 +Ethernet176 241,242,243,244,245,246,247,248 Eth23/1 23 400000 +Ethernet184 249,250,251,252,253,254,255,256 Eth24/1 24 400000 +Ethernet192 161,162,163,164,165,166,167,168 Eth25/1 25 400000 +Ethernet200 169,170,171,172,173,174,175,176 Eth26/1 26 400000 +Ethernet208 177,178,179,180,181,182,183,184 Eth27/1 27 400000 +Ethernet216 185,186,187,188,189,190,191,192 Eth28/1 28 400000 +Ethernet224 193,194,195,196,197,198,199,200 Eth29/1 29 400000 +Ethernet232 201,202,203,204,205,206,207,208 Eth30/1 30 400000 +Ethernet240 209,210,211,212,213,214,215,216 Eth31/1 31 400000 +Ethernet248 217,218,219,220,221,222,223,224 Eth32/1 32 400000 diff --git a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm index 400fbdcf75..ec154e12e6 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm +++ b/device/celestica/x86_64-cel_silverstone-r0/Silverstone/th3-32x400G.config.bcm @@ -1,5 +1,5 @@ -pbmp_xport_xe.0=0x8111181111c1111811118111181111c111182222 +pbmp_xport_xe.0=0x8ffff8ffffcffff8ffff8ffff8ffffcffff8ffff ccm_dma_enable=0 ccmdma_intr_enable=0 ctr_evict_enable=0 @@ -10,8 +10,6 @@ phy_enable=0 phy_null=1 pll_bypass=1 -init_all_modules=0 - sai_tunnel_global_sip_mask_enable=1 @@ -183,38 +181,38 @@ serdes_core_tx_polarity_flip_physical{209}=0xe9 serdes_core_rx_polarity_flip_physical{217}=0xec serdes_core_tx_polarity_flip_physical{217}=0x68 -dport_map_port_20=1 -dport_map_port_24=2 -dport_map_port_28=3 -dport_map_port_32=4 -dport_map_port_40=5 -dport_map_port_44=6 -dport_map_port_48=7 -dport_map_port_52=8 -dport_map_port_1=9 -dport_map_port_5=10 -dport_map_port_9=11 -dport_map_port_13=12 -dport_map_port_60=13 -dport_map_port_64=14 -dport_map_port_68=15 -dport_map_port_72=16 -dport_map_port_80=17 -dport_map_port_84=18 -dport_map_port_88=19 -dport_map_port_92=20 -dport_map_port_140=21 -dport_map_port_144=22 -dport_map_port_148=23 -dport_map_port_152=24 -dport_map_port_100=25 -dport_map_port_104=26 -dport_map_port_108=27 -dport_map_port_112=28 -dport_map_port_120=29 -dport_map_port_124=30 -dport_map_port_128=31 -dport_map_port_132=32 +#dport_map_port_20=1 +#dport_map_port_24=2 +#dport_map_port_28=3 +#dport_map_port_32=4 +#dport_map_port_40=5 +#dport_map_port_44=6 +#dport_map_port_48=7 +#dport_map_port_52=8 +#dport_map_port_1=9 +#dport_map_port_5=10 +#dport_map_port_9=11 +#dport_map_port_13=12 +#dport_map_port_60=13 +#dport_map_port_64=14 +#dport_map_port_68=15 +#dport_map_port_72=16 +#dport_map_port_80=17 +#dport_map_port_84=18 +#dport_map_port_88=19 +#dport_map_port_92=20 +#dport_map_port_140=21 +#dport_map_port_144=22 +#dport_map_port_148=23 +#dport_map_port_152=24 +#dport_map_port_100=25 +#dport_map_port_104=26 +#dport_map_port_108=27 +#dport_map_port_112=28 +#dport_map_port_120=29 +#dport_map_port_124=30 +#dport_map_port_128=31 +#dport_map_port_132=32 #dport_map_port_38=33 #dport_map_port_118=34 diff --git a/device/celestica/x86_64-cel_silverstone-r0/pcie.yaml b/device/celestica/x86_64-cel_silverstone-r0/pcie.yaml new file mode 100644 index 0000000000..2249ead1a8 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/pcie.yaml @@ -0,0 +1,434 @@ +- bus: '00' + dev: '00' + fn: '0' + id: 6f00 + name: 'Host bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D DMI2 + (rev 03)' +- bus: '00' + dev: '01' + fn: '0' + id: 6f02 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 1 (rev 03)' +- bus: '00' + dev: '02' + fn: '0' + id: 6f04 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '02' + fn: '2' + id: 6f06 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 2 (rev 03)' +- bus: '00' + dev: '03' + fn: '0' + id: 6f08 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '1' + id: 6f09 + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '2' + id: 6f0a + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '03' + fn: '3' + id: 6f0b + name: 'PCI bridge: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D PCI + Express Root Port 3 (rev 03)' +- bus: '00' + dev: '05' + fn: '0' + id: 6f28 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Map/VTd_Misc/System Management (rev 03)' +- bus: '00' + dev: '05' + fn: '1' + id: 6f29 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO Hot Plug (rev 03)' +- bus: '00' + dev: '05' + fn: '2' + id: 6f2a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D IIO RAS/Control Status/Global Errors (rev 03)' +- bus: '00' + dev: '05' + fn: '4' + id: 6f2c + name: 'PIC: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon D I/O APIC (rev + 03)' +- bus: '00' + dev: 1c + fn: '0' + id: 8c10 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #1 (rev d5)' +- bus: '00' + dev: 1c + fn: '1' + id: 8c12 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #2 (rev d5)' +- bus: '00' + dev: 1c + fn: '2' + id: 8c14 + name: 'PCI bridge: Intel Corporation 8 Series/C220 Series Chipset Family PCI Express + Root Port #3 (rev d5)' +- bus: '00' + dev: 1d + fn: '0' + id: 8c26 + name: 'USB controller: Intel Corporation 8 Series/C220 Series Chipset Family USB + EHCI #1 (rev 05)' +- bus: '00' + dev: 1f + fn: '0' + id: 8c54 + name: 'ISA bridge: Intel Corporation C224 Series Chipset Family Server Standard + SKU LPC Controller (rev 05)' +- bus: '00' + dev: 1f + fn: '2' + id: 8c02 + name: 'SATA controller: Intel Corporation 8 Series/C220 Series Chipset Family 6-port + SATA Controller 1 [AHCI mode] (rev 05)' +- bus: '00' + dev: 1f + fn: '3' + id: 8c22 + name: 'SMBus: Intel Corporation 8 Series/C220 Series Chipset Family SMBus Controller + (rev 05)' +- bus: '02' + dev: '00' + fn: '0' + id: 6f50 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 0' +- bus: '02' + dev: '00' + fn: '1' + id: 6f51 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 1' +- bus: '02' + dev: '00' + fn: '2' + id: 6f52 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 2' +- bus: '02' + dev: '00' + fn: '3' + id: 6f53 + name: 'System peripheral: Intel Corporation Xeon Processor D Family QuickData Technology + Register DMA Channel 3' +- bus: '03' + dev: '00' + fn: '0' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '03' + dev: '00' + fn: '1' + id: 15ab + name: 'Ethernet controller: Intel Corporation Ethernet Connection X552 10 GbE Backplane' +- bus: '05' + dev: '00' + fn: '0' + id: b980 + name: 'Ethernet controller: Broadcom Inc. and subsidiaries Device b980 (rev 11)' +- bus: 09 + dev: '00' + fn: '0' + id: '7021' + name: 'Memory controller: Xilinx Corporation Device 7021' +- bus: 0a + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: 0b + dev: '00' + fn: '0' + id: '1533' + name: 'Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev + 03)' +- bus: ff + dev: 0b + fn: '0' + id: 6f81 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '1' + id: 6f36 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '2' + id: 6f37 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link 0/1 (rev 03)' +- bus: ff + dev: 0b + fn: '3' + id: 6f76 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R3 QPI Link Debug (rev 03)' +- bus: ff + dev: 0c + fn: '0' + id: 6fe0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0c + fn: '1' + id: 6fe1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '0' + id: 6ff8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '4' + id: 6ffc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '5' + id: 6ffd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: 0f + fn: '6' + id: 6ffe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Caching Agent (rev 03)' +- bus: ff + dev: '10' + fn: '0' + id: 6f1d + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '1' + id: 6f34 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D R2PCIe Agent (rev 03)' +- bus: ff + dev: '10' + fn: '5' + id: 6f1e + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '6' + id: 6f7d + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '10' + fn: '7' + id: 6f1f + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Ubox (rev 03)' +- bus: ff + dev: '12' + fn: '0' + id: 6fa0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '12' + fn: '1' + id: 6f30 + name: 'Performance counters: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Home Agent 0 (rev 03)' +- bus: ff + dev: '13' + fn: '0' + id: 6fa8 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '1' + id: 6f71 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Target Address/Thermal/RAS (rev 03)' +- bus: ff + dev: '13' + fn: '2' + id: 6faa + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '3' + id: 6fab + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '4' + id: 6fac + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '5' + id: 6fad + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel Target Address Decoder (rev 03)' +- bus: ff + dev: '13' + fn: '6' + id: 6fae + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Broadcast (rev 03)' +- bus: ff + dev: '13' + fn: '7' + id: 6faf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Global Broadcast (rev 03)' +- bus: ff + dev: '14' + fn: '0' + id: 6fb0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '1' + id: 6fb1 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Thermal Control (rev 03)' +- bus: ff + dev: '14' + fn: '2' + id: 6fb2 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 0 Error (rev 03)' +- bus: ff + dev: '14' + fn: '3' + id: 6fb3 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 1 Error (rev 03)' +- bus: ff + dev: '14' + fn: '4' + id: 6fbc + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '5' + id: 6fbd + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '6' + id: 6fbe + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '14' + fn: '7' + id: 6fbf + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D DDRIO Channel 0/1 Interface (rev 03)' +- bus: ff + dev: '15' + fn: '0' + id: 6fb4 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '1' + id: 6fb5 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Thermal Control (rev 03)' +- bus: ff + dev: '15' + fn: '2' + id: 6fb6 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 2 Error (rev 03)' +- bus: ff + dev: '15' + fn: '3' + id: 6fb7 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Memory Controller 0 - Channel 3 Error (rev 03)' +- bus: ff + dev: 1e + fn: '0' + id: 6f98 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '1' + id: 6f99 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '2' + id: 6f9a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '3' + id: 6fc0 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1e + fn: '4' + id: 6f9c + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '0' + id: 6f88 + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' +- bus: ff + dev: 1f + fn: '2' + id: 6f8a + name: 'System peripheral: Intel Corporation Xeon E7 v4/Xeon E5 v4/Xeon E3 v4/Xeon + D Power Control Unit (rev 03)' diff --git a/device/celestica/x86_64-cel_silverstone-r0/platform.json b/device/celestica/x86_64-cel_silverstone-r0/platform.json new file mode 100644 index 0000000000..6dc768bd46 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/platform.json @@ -0,0 +1,484 @@ +{ + "interfaces": { + "Ethernet0": { + "index": "1,1,1,1,1,1,1,1", + "lanes": "33,34,35,36,37,38,39,40", + "breakout_modes": { + "1x400G": ["Eth1/1"], + "2x100G": ["Eth1/1", "Eth1/5"], + "2x40G": ["Eth1/1", "Eth1/5"], + "4x100G": ["Eth1/1", "Eth1/3", "Eth1/5", "Eth1/7"], + "1x100G(2)": ["Eth1/1"], + "1x100G(4)": ["Eth1/1"], + "1x40G(4)": ["Eth1/1"], + "4x25G(4)": ["Eth1/1", "Eth1/2", "Eth1/3", "Eth1/4"], + "4x10G(4)": ["Eth1/1", "Eth1/2", "Eth1/3", "Eth1/4"] + } + }, + "Ethernet8": { + "index": "2,2,2,2,2,2,2,2", + "lanes": "41,42,43,44,45,46,47,48", + "breakout_modes": { + "1x400G": ["Eth2/1"], + "2x100G": ["Eth2/1", "Eth2/5"], + "2x40G": ["Eth2/1", "Eth2/5"], + "4x100G": ["Eth2/1", "Eth2/3", "Eth2/5", "Eth2/7"], + "1x100G(2)": ["Eth2/1"], + "1x100G(4)": ["Eth2/1"], + "1x40G(4)": ["Eth2/1"], + "4x25G(4)": ["Eth2/1", "Eth2/2", "Eth2/3", "Eth2/4"], + "4x10G(4)": ["Eth2/1", "Eth2/2", "Eth2/3", "Eth2/4"] + } + }, + "Ethernet16": { + "index": "3,3,3,3,3,3,3,3", + "lanes": "49,50,51,52,53,54,55,56", + "breakout_modes": { + "1x400G": ["Eth3/1"], + "2x100G": ["Eth3/1", "Eth3/5"], + "2x40G": ["Eth3/1", "Eth3/5"], + "4x100G": ["Eth3/1", "Eth3/3", "Eth3/5", "Eth3/7"], + "1x100G(2)": ["Eth3/1"], + "1x100G(4)": ["Eth3/1"], + "1x40G(4)": ["Eth3/1"], + "4x25G(4)": ["Eth3/1", "Eth3/2", "Eth3/3", "Eth3/4"], + "4x10G(4)": ["Eth3/1", "Eth3/2", "Eth3/3", "Eth3/4"] + } + }, + "Ethernet24": { + "index": "4,4,4,4,4,4,4,4", + "lanes": "57,58,59,60,61,62,63,64", + "breakout_modes": { + "1x400G": ["Eth4/1"], + "2x100G": ["Eth4/1", "Eth4/5"], + "2x40G": ["Eth4/1", "Eth4/5"], + "4x100G": ["Eth4/1", "Eth4/3", "Eth4/5", "Eth4/7"], + "1x100G(2)": ["Eth4/1"], + "1x100G(4)": ["Eth4/1"], + "1x40G(4)": ["Eth4/1"], + "4x25G(4)": ["Eth4/1", "Eth4/2", "Eth4/3", "Eth4/4"], + "4x10G(4)": ["Eth4/1", "Eth4/2", "Eth4/3", "Eth4/4"] + } + }, + "Ethernet32": { + "index": "5,5,5,5,5,5,5,5", + "lanes": "65,66,67,68,69,70,71,72", + "breakout_modes": { + "1x400G": ["Eth5/1"], + "2x100G": ["Eth5/1", "Eth5/5"], + "2x40G": ["Eth5/1", "Eth5/5"], + "4x100G": ["Eth5/1", "Eth5/3", "Eth5/5", "Eth5/7"], + "1x100G(2)": ["Eth5/1"], + "1x100G(4)": ["Eth5/1"], + "1x40G(4)": ["Eth5/1"], + "4x25G(4)": ["Eth5/1", "Eth5/2", "Eth5/3", "Eth5/4"], + "4x10G(4)": ["Eth5/1", "Eth5/2", "Eth5/3", "Eth5/4"] + } + }, + "Ethernet40": { + "index": "6,6,6,6,6,6,6,6", + "lanes": "73,74,75,76,77,78,79,80", + "breakout_modes": { + "1x400G": ["Eth6/1"], + "2x100G": ["Eth6/1", "Eth6/5"], + "2x40G": ["Eth6/1", "Eth6/5"], + "4x100G": ["Eth6/1", "Eth6/3", "Eth6/5", "Eth6/7"], + "1x100G(2)": ["Eth6/1"], + "1x100G(4)": ["Eth6/1"], + "1x40G(4)": ["Eth6/1"], + "4x25G(4)": ["Eth6/1", "Eth6/2", "Eth6/3", "Eth6/4"], + "4x10G(4)": ["Eth6/1", "Eth6/2", "Eth6/3", "Eth6/4"] + } + }, + "Ethernet48": { + "index": "7,7,7,7,7,7,7,7", + "lanes": "81,82,83,84,85,86,87,88", + "breakout_modes": { + "1x400G": ["Eth7/1"], + "2x100G": ["Eth7/1", "Eth7/5"], + "2x40G": ["Eth7/1", "Eth7/5"], + "4x100G": ["Eth7/1", "Eth7/3", "Eth7/5", "Eth7/7"], + "1x100G(2)": ["Eth7/1"], + "1x100G(4)": ["Eth7/1"], + "1x40G(4)": ["Eth7/1"], + "4x25G(4)": ["Eth7/1", "Eth7/2", "Eth7/3", "Eth7/4"], + "4x10G(4)": ["Eth7/1", "Eth7/2", "Eth7/3", "Eth7/4"] + } + }, + "Ethernet56": { + "index": "8,8,8,8,8,8,8,8", + "lanes": "89,90,91,92,93,94,95,96", + "breakout_modes": { + "1x400G": ["Eth8/1"], + "2x100G": ["Eth8/1", "Eth8/5"], + "2x40G": ["Eth8/1", "Eth8/5"], + "4x100G": ["Eth8/1", "Eth8/3", "Eth8/5", "Eth8/7"], + "1x100G(2)": ["Eth8/1"], + "1x100G(4)": ["Eth8/1"], + "1x40G(4)": ["Eth8/1"], + "4x25G(4)": ["Eth8/1", "Eth8/2", "Eth8/3", "Eth8/4"], + "4x10G(4)": ["Eth8/1", "Eth8/2", "Eth8/3", "Eth8/4"] + } + }, + "Ethernet64": { + "index": "9,9,9,9,9,9,9,9", + "lanes": "1,2,3,4,5,6,7,8", + "breakout_modes": { + "1x400G": ["Eth9/1"], + "2x100G": ["Eth9/1", "Eth9/5"], + "2x40G": ["Eth9/1", "Eth9/5"], + "4x100G": ["Eth9/1", "Eth9/3", "Eth9/5", "Eth9/7"], + "1x100G(2)": ["Eth9/1"], + "1x100G(4)": ["Eth9/1"], + "1x40G(4)": ["Eth9/1"], + "4x25G(4)": ["Eth9/1", "Eth9/2", "Eth9/3", "Eth9/4"], + "4x10G(4)": ["Eth9/1", "Eth9/2", "Eth9/3", "Eth9/4"] + } + }, + "Ethernet72": { + "index": "10,10,10,10,10,10,10,10", + "lanes": "9,10,11,12,13,14,15,16", + "breakout_modes": { + "1x400G": ["Eth10/1"], + "2x100G": ["Eth10/1", "Eth10/5"], + "2x40G": ["Eth10/1", "Eth10/5"], + "4x100G": ["Eth10/1", "Eth10/3", "Eth10/5", "Eth10/7"], + "1x100G(2)": ["Eth10/1"], + "1x100G(4)": ["Eth10/1"], + "1x40G(4)": ["Eth10/1"], + "4x25G(4)": ["Eth10/1", "Eth10/2", "Eth10/3", "Eth10/4"], + "4x10G(4)": ["Eth10/1", "Eth10/2", "Eth10/3", "Eth10/4"] + } + }, + "Ethernet80": { + "index": "11,11,11,11,11,11,11,11", + "lanes": "17,18,19,20,21,22,23,24", + "breakout_modes": { + "1x400G": ["Eth11/1"], + "2x100G": ["Eth11/1", "Eth11/5"], + "2x40G": ["Eth11/1", "Eth11/5"], + "4x100G": ["Eth11/1", "Eth11/3", "Eth11/5", "Eth11/7"], + "1x100G(2)": ["Eth11/1"], + "1x100G(4)": ["Eth11/1"], + "1x40G(4)": ["Eth11/1"], + "4x25G(4)": ["Eth11/1", "Eth11/2", "Eth11/3", "Eth11/4"], + "4x10G(4)": ["Eth11/1", "Eth11/2", "Eth11/3", "Eth11/4"] + } + }, + "Ethernet88": { + "index": "12,12,12,12,12,12,12,12", + "lanes": "25,26,27,28,29,30,31,32", + "breakout_modes": { + "1x400G": ["Eth12/1"], + "2x100G": ["Eth12/1", "Eth12/5"], + "2x40G": ["Eth12/1", "Eth12/5"], + "4x100G": ["Eth12/1", "Eth12/3", "Eth12/5", "Eth12/7"], + "1x100G(2)": ["Eth12/1"], + "1x100G(4)": ["Eth12/1"], + "1x40G(4)": ["Eth12/1"], + "4x25G(4)": ["Eth12/1", "Eth12/2", "Eth12/3", "Eth12/4"], + "4x10G(4)": ["Eth12/1", "Eth12/2", "Eth12/3", "Eth12/4"] + } + }, + "Ethernet96": { + "index": "13,13,13,13,13,13,13,13", + "lanes": "97,98,99,100,101,102,103,104", + "breakout_modes": { + "1x400G": ["Eth13/1"], + "2x100G": ["Eth13/1", "Eth13/5"], + "2x40G": ["Eth13/1", "Eth13/5"], + "4x100G": ["Eth13/1", "Eth13/3", "Eth13/5", "Eth13/7"], + "1x100G(2)": ["Eth13/1"], + "1x100G(4)": ["Eth13/1"], + "1x40G(4)": ["Eth13/1"], + "4x25G(4)": ["Eth13/1", "Eth13/2", "Eth13/3", "Eth13/4"], + "4x10G(4)": ["Eth13/1", "Eth13/2", "Eth13/3", "Eth13/4"] + } + }, + "Ethernet104": { + "index": "14,14,14,14,14,14,14,14", + "lanes": "105,106,107,108,109,110,111,112", + "breakout_modes": { + "1x400G": ["Eth14/1"], + "2x100G": ["Eth14/1", "Eth14/5"], + "2x40G": ["Eth14/1", "Eth14/5"], + "4x100G": ["Eth14/1", "Eth14/3", "Eth14/5", "Eth14/7"], + "1x100G(2)": ["Eth14/1"], + "1x100G(4)": ["Eth14/1"], + "1x40G(4)": ["Eth14/1"], + "4x25G(4)": ["Eth14/1", "Eth14/2", "Eth14/3", "Eth14/4"], + "4x10G(4)": ["Eth14/1", "Eth14/2", "Eth14/3", "Eth14/4"] + } + }, + "Ethernet112": { + "index": "15,15,15,15,15,15,15,15", + "lanes": "113,114,115,116,117,118,119,120", + "breakout_modes": { + "1x400G": ["Eth15/1"], + "2x100G": ["Eth15/1", "Eth15/5"], + "2x40G": ["Eth15/1", "Eth15/5"], + "4x100G": ["Eth15/1", "Eth15/3", "Eth15/5", "Eth15/7"], + "1x100G(2)": ["Eth15/1"], + "1x100G(4)": ["Eth15/1"], + "1x40G(4)": ["Eth15/1"], + "4x25G(4)": ["Eth15/1", "Eth15/2", "Eth15/3", "Eth15/4"], + "4x10G(4)": ["Eth15/1", "Eth15/2", "Eth15/3", "Eth15/4"] + } + }, + "Ethernet120": { + "index": "16,16,16,16,16,16,16,16", + "lanes": "121,122,123,124,125,126,127,128", + "breakout_modes": { + "1x400G": ["Eth16/1"], + "2x100G": ["Eth16/1", "Eth16/5"], + "2x40G": ["Eth16/1", "Eth16/5"], + "4x100G": ["Eth16/1", "Eth16/3", "Eth16/5", "Eth16/7"], + "1x100G(2)": ["Eth16/1"], + "1x100G(4)": ["Eth16/1"], + "1x40G(4)": ["Eth16/1"], + "4x25G(4)": ["Eth16/1", "Eth16/2", "Eth16/3", "Eth16/4"], + "4x10G(4)": ["Eth16/1", "Eth16/2", "Eth16/3", "Eth16/4"] + } + }, + "Ethernet128": { + "index": "17,17,17,17,17,17,17,17", + "lanes": "129,130,131,132,133,134,135,136", + "breakout_modes": { + "1x400G": ["Eth17/1"], + "2x100G": ["Eth17/1", "Eth17/5"], + "2x40G": ["Eth17/1", "Eth17/5"], + "4x100G": ["Eth17/1", "Eth17/3", "Eth17/5", "Eth17/7"], + "1x100G(2)": ["Eth17/1"], + "1x100G(4)": ["Eth17/1"], + "1x40G(4)": ["Eth17/1"], + "4x25G(4)": ["Eth17/1", "Eth17/2", "Eth17/3", "Eth17/4"], + "4x10G(4)": ["Eth17/1", "Eth17/2", "Eth17/3", "Eth17/4"] + } + }, + "Ethernet136": { + "index": "18,18,18,18,18,18,18,18", + "lanes": "137,138,139,140,141,142,143,144", + "breakout_modes": { + "1x400G": ["Eth18/1"], + "2x100G": ["Eth18/1", "Eth18/5"], + "2x40G": ["Eth18/1", "Eth18/5"], + "4x100G": ["Eth18/1", "Eth18/3", "Eth18/5", "Eth18/7"], + "1x100G(2)": ["Eth18/1"], + "1x100G(4)": ["Eth18/1"], + "1x40G(4)": ["Eth18/1"], + "4x25G(4)": ["Eth18/1", "Eth18/2", "Eth18/3", "Eth18/4"], + "4x10G(4)": ["Eth18/1", "Eth18/2", "Eth18/3", "Eth18/4"] + } + }, + "Ethernet144": { + "index": "19,19,19,19,19,19,19,19", + "lanes": "145,146,147,148,149,150,151,152", + "breakout_modes": { + "1x400G": ["Eth19/1"], + "2x100G": ["Eth19/1", "Eth19/5"], + "2x40G": ["Eth19/1", "Eth19/5"], + "4x100G": ["Eth19/1", "Eth19/3", "Eth19/5", "Eth19/7"], + "1x100G(2)": ["Eth19/1"], + "1x100G(4)": ["Eth19/1"], + "1x40G(4)": ["Eth19/1"], + "4x25G(4)": ["Eth19/1", "Eth19/2", "Eth19/3", "Eth19/4"], + "4x10G(4)": ["Eth19/1", "Eth19/2", "Eth19/3", "Eth19/4"] + } + }, + "Ethernet152": { + "index": "20,20,20,20,20,20,20,20", + "lanes": "153,154,155,156,157,158,159,160", + "breakout_modes": { + "1x400G": ["Eth20/1"], + "2x100G": ["Eth20/1", "Eth20/5"], + "2x40G": ["Eth20/1", "Eth20/5"], + "4x100G": ["Eth20/1", "Eth20/3", "Eth20/5", "Eth20/7"], + "1x100G(2)": ["Eth20/1"], + "1x100G(4)": ["Eth20/1"], + "1x40G(4)": ["Eth20/1"], + "4x25G(4)": ["Eth20/1", "Eth20/2", "Eth20/3", "Eth20/4"], + "4x10G(4)": ["Eth20/1", "Eth20/2", "Eth20/3", "Eth20/4"] + } + }, + "Ethernet160": { + "index": "21,21,21,21,21,21,21,21", + "lanes": "225,226,227,228,229,230,231,232", + "breakout_modes": { + "1x400G": ["Eth21/1"], + "2x100G": ["Eth21/1", "Eth21/5"], + "2x40G": ["Eth21/1", "Eth21/5"], + "4x100G": ["Eth21/1", "Eth21/3", "Eth21/5", "Eth21/7"], + "1x100G(2)": ["Eth21/1"], + "1x100G(4)": ["Eth21/1"], + "1x40G(4)": ["Eth21/1"], + "4x25G(4)": ["Eth21/1", "Eth21/2", "Eth21/3", "Eth21/4"], + "4x10G(4)": ["Eth21/1", "Eth21/2", "Eth21/3", "Eth21/4"] + } + }, + "Ethernet168": { + "index": "22,22,22,22,22,22,22,22", + "lanes": "233,234,235,236,237,238,239,240", + "breakout_modes": { + "1x400G": ["Eth22/1"], + "2x100G": ["Eth22/1", "Eth22/5"], + "2x40G": ["Eth22/1", "Eth22/5"], + "4x100G": ["Eth22/1", "Eth22/3", "Eth22/5", "Eth22/7"], + "1x100G(2)": ["Eth22/1"], + "1x100G(4)": ["Eth22/1"], + "1x40G(4)": ["Eth22/1"], + "4x25G(4)": ["Eth22/1", "Eth22/2", "Eth22/3", "Eth22/4"], + "4x10G(4)": ["Eth22/1", "Eth22/2", "Eth22/3", "Eth22/4"] + } + }, + "Ethernet176": { + "index": "23,23,23,23,23,23,23,23", + "lanes": "241,242,243,244,245,246,247,248", + "breakout_modes": { + "1x400G": ["Eth23/1"], + "2x100G": ["Eth23/1", "Eth23/5"], + "2x40G": ["Eth23/1", "Eth23/5"], + "4x100G": ["Eth23/1", "Eth23/3", "Eth23/5", "Eth23/7"], + "1x100G(2)": ["Eth23/1"], + "1x100G(4)": ["Eth23/1"], + "1x40G(4)": ["Eth23/1"], + "4x25G(4)": ["Eth23/1", "Eth23/2", "Eth23/3", "Eth23/4"], + "4x10G(4)": ["Eth23/1", "Eth23/2", "Eth23/3", "Eth23/4"] + } + }, + "Ethernet184": { + "index": "24,24,24,24,24,24,24,24", + "lanes": "249,250,251,252,253,254,255,256", + "breakout_modes": { + "1x400G": ["Eth24/1"], + "2x100G": ["Eth24/1", "Eth24/5"], + "2x40G": ["Eth24/1", "Eth24/5"], + "4x100G": ["Eth24/1", "Eth24/3", "Eth24/5", "Eth24/7"], + "1x100G(2)": ["Eth24/1"], + "1x100G(4)": ["Eth24/1"], + "1x40G(4)": ["Eth24/1"], + "4x25G(4)": ["Eth24/1", "Eth24/2", "Eth24/3", "Eth24/4"], + "4x10G(4)": ["Eth24/1", "Eth24/2", "Eth24/3", "Eth24/4"] + } + }, + "Ethernet192": { + "index": "25,25,25,25,25,25,25,25", + "lanes": "161,162,163,164,165,166,167,168", + "breakout_modes": { + "1x400G": ["Eth25/1"], + "2x100G": ["Eth25/1", "Eth25/5"], + "2x40G": ["Eth25/1", "Eth25/5"], + "4x100G": ["Eth25/1", "Eth25/3", "Eth25/5", "Eth25/7"], + "1x100G(2)": ["Eth25/1"], + "1x100G(4)": ["Eth25/1"], + "1x40G(4)": ["Eth25/1"], + "4x25G(4)": ["Eth25/1", "Eth25/2", "Eth25/3", "Eth25/4"], + "4x10G(4)": ["Eth25/1", "Eth25/2", "Eth25/3", "Eth25/4"] + } + }, + "Ethernet200": { + "index": "26,26,26,26,26,26,26,26", + "lanes": "169,170,171,172,173,174,175,176", + "breakout_modes": { + "1x400G": ["Eth26/1"], + "2x100G": ["Eth26/1", "Eth26/5"], + "2x40G": ["Eth26/1", "Eth26/5"], + "4x100G": ["Eth26/1", "Eth26/3", "Eth26/5", "Eth26/7"], + "1x100G(2)": ["Eth26/1"], + "1x100G(4)": ["Eth26/1"], + "1x40G(4)": ["Eth26/1"], + "4x25G(4)": ["Eth26/1", "Eth26/2", "Eth26/3", "Eth26/4"], + "4x10G(4)": ["Eth26/1", "Eth26/2", "Eth26/3", "Eth26/4"] + } + }, + "Ethernet208": { + "index": "27,27,27,27,27,27,27,27", + "lanes": "177,178,179,180,181,182,183,184", + "breakout_modes": { + "1x400G": ["Eth27/1"], + "2x100G": ["Eth27/1", "Eth27/5"], + "2x40G": ["Eth27/1", "Eth27/5"], + "4x100G": ["Eth27/1", "Eth27/3", "Eth27/5", "Eth27/7"], + "1x100G(2)": ["Eth27/1"], + "1x100G(4)": ["Eth27/1"], + "1x40G(4)": ["Eth27/1"], + "4x25G(4)": ["Eth27/1", "Eth27/2", "Eth27/3", "Eth27/4"], + "4x10G(4)": ["Eth27/1", "Eth27/2", "Eth27/3", "Eth27/4"] + } + }, + "Ethernet216": { + "index": "28,28,28,28,28,28,28,28", + "lanes": "185,186,187,188,189,190,191,192", + "breakout_modes": { + "1x400G": ["Eth28/1"], + "2x100G": ["Eth28/1", "Eth28/5"], + "2x40G": ["Eth28/1", "Eth28/5"], + "4x100G": ["Eth28/1", "Eth28/3", "Eth28/5", "Eth28/7"], + "1x100G(2)": ["Eth28/1"], + "1x100G(4)": ["Eth28/1"], + "1x40G(4)": ["Eth28/1"], + "4x25G(4)": ["Eth28/1", "Eth28/2", "Eth28/3", "Eth28/4"], + "4x10G(4)": ["Eth28/1", "Eth28/2", "Eth28/3", "Eth28/4"] + } + }, + "Ethernet224": { + "index": "29,29,29,29,29,29,29,29", + "lanes": "193,194,195,196,197,198,199,200", + "breakout_modes": { + "1x400G": ["Eth29/1"], + "2x100G": ["Eth29/1", "Eth29/5"], + "2x40G": ["Eth29/1", "Eth29/5"], + "4x100G": ["Eth29/1", "Eth29/3", "Eth29/5", "Eth29/7"], + "1x100G(2)": ["Eth29/1"], + "1x100G(4)": ["Eth29/1"], + "1x40G(4)": ["Eth29/1"], + "4x25G(4)": ["Eth29/1", "Eth29/2", "Eth29/3", "Eth29/4"], + "4x10G(4)": ["Eth29/1", "Eth29/2", "Eth29/3", "Eth29/4"] + } + }, + "Ethernet232": { + "index": "30,30,30,30,30,30,30,30", + "lanes": "201,202,203,204,205,206,207,208", + "breakout_modes": { + "1x400G": ["Eth30/1"], + "2x100G": ["Eth30/1", "Eth30/5"], + "2x40G": ["Eth30/1", "Eth30/5"], + "4x100G": ["Eth30/1", "Eth30/3", "Eth30/5", "Eth30/7"], + "1x100G(2)": ["Eth30/1"], + "1x100G(4)": ["Eth30/1"], + "1x40G(4)": ["Eth30/1"], + "4x25G(4)": ["Eth30/1", "Eth30/2", "Eth30/3", "Eth30/4"], + "4x10G(4)": ["Eth30/1", "Eth30/2", "Eth30/3", "Eth30/4"] + } + }, + "Ethernet240": { + "index": "31,31,31,31,31,31,31,31", + "lanes": "209,210,211,212,213,214,215,216", + "breakout_modes": { + "1x400G": ["Eth31/1"], + "2x100G": ["Eth31/1", "Eth31/5"], + "2x40G": ["Eth31/1", "Eth31/5"], + "4x100G": ["Eth31/1", "Eth31/3", "Eth31/5", "Eth31/7"], + "1x100G(2)": ["Eth31/1"], + "1x100G(4)": ["Eth31/1"], + "1x40G(4)": ["Eth31/1"], + "4x25G(4)": ["Eth31/1", "Eth31/2", "Eth31/3", "Eth31/4"], + "4x10G(4)": ["Eth31/1", "Eth31/2", "Eth31/3", "Eth31/4"] + } + }, + "Ethernet248": { + "index": "32,32,32,32,32,32,32,32", + "lanes": "217,218,219,220,221,222,223,224", + "breakout_modes": { + "1x400G": ["Eth32/1"], + "2x100G": ["Eth32/1", "Eth32/5"], + "2x40G": ["Eth32/1", "Eth32/5"], + "4x100G": ["Eth32/1", "Eth32/3", "Eth32/5", "Eth32/7"], + "1x100G(2)": ["Eth32/1"], + "1x100G(4)": ["Eth32/1"], + "1x40G(4)": ["Eth32/1"], + "4x25G(4)": ["Eth32/1", "Eth32/2", "Eth32/3", "Eth32/4"], + "4x10G(4)": ["Eth32/1", "Eth32/2", "Eth32/3", "Eth32/4"] + } + } + } +} diff --git a/device/celestica/x86_64-cel_silverstone-r0/platform_components.json b/device/celestica/x86_64-cel_silverstone-r0/platform_components.json new file mode 100644 index 0000000000..9713fd620c --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/platform_components.json @@ -0,0 +1,18 @@ +{ + "chassis": { + "Silverstone": { + "component": { + "BIOS": {}, + "ONIE": {}, + "BMC": {}, + "FPGA": {}, + "CPLD COMe": {}, + "CPLD BASE": {}, + "CPLD SW1": {}, + "CPLD SW2": {}, + "CPLD FAN": {}, + "SSD": {} + } + } + } +} diff --git a/device/celestica/x86_64-cel_silverstone-r0/platform_reboot b/device/celestica/x86_64-cel_silverstone-r0/platform_reboot new file mode 100755 index 0000000000..0c84c4d7f5 --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/platform_reboot @@ -0,0 +1,6 @@ +#!/bin/bash + +# Set all LEDs to BMC's control +ipmitool raw 0x3a 0x09 0x02 0x01 &> /dev/null + +/usr/local/bin/silverstone_platform_shutdown.sh system diff --git a/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py b/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py index 46684aae0f..ca75ad9833 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py +++ b/device/celestica/x86_64-cel_silverstone-r0/plugins/psuutil.py @@ -1,3 +1,4 @@ +import os.path import subprocess import sys import re @@ -12,13 +13,13 @@ class PsuUtil(PsuBase): """Platform-specific PSUutil class""" def __init__(self): - self.ipmi_raw = ["docker", "exec", "-ti", "pmon", "ipmitool", "raw", "0x4", "0x2d", ""] + self.ipmi_raw = "docker exec -ti pmon ipmitool raw 0x4 0x2d" self.psu1_id = "0x2f" self.psu2_id = "0x39" PsuBase.__init__(self) def run_command(self, command): - proc = subprocess.Popen(command, universal_newlines=True, stdout=subprocess.PIPE) + proc = subprocess.Popen(command, shell=True, universal_newlines=True, stdout=subprocess.PIPE) (out, err) = proc.communicate() if proc.returncode != 0: @@ -51,8 +52,7 @@ class PsuUtil(PsuBase): return False psu_id = self.psu1_id if index == 1 else self.psu2_id - self.ipmi_raw[8] = psu_id - res_string = self.run_command(self.ipmi_raw) + res_string = self.run_command(self.ipmi_raw + ' ' + psu_id) status_byte = self.find_value(res_string) if status_byte is None: @@ -76,8 +76,7 @@ class PsuUtil(PsuBase): return False psu_id = self.psu1_id if index == 1 else self.psu2_id - self.ipmi_raw[8] = psu_id - res_string = self.run_command(self.ipmi_raw) + res_string = self.run_command(self.ipmi_raw + ' ' + psu_id) status_byte = self.find_value(res_string) if status_byte is None: diff --git a/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json index 94592fa8ce..f5b2736b13 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json +++ b/device/celestica/x86_64-cel_silverstone-r0/pmon_daemon_control.json @@ -1,3 +1,5 @@ { - "skip_ledd": true + "skip_ledd": true, + "skip_fancontrol": true, + "skip_xcvrd_cmis_mgr": true } diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py deleted file mode 100644 index d82f374931..0000000000 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -__all__ = ["platform", "chassis"] -from sonic_platform import * diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py deleted file mode 100644 index b6f77cbd3d..0000000000 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/chassis.py +++ /dev/null @@ -1,131 +0,0 @@ -############################################################################# -# 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.component import Component - from sonic_platform.eeprom import Tlv - from sonic_platform.fan import Fan - from sonic_platform.sfp import Sfp - from sonic_platform.psu import Psu - from sonic_platform.thermal import Thermal - from .helper import APIHelper -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -NUM_FAN_TRAY = 7 -NUM_FAN = 2 -NUM_PSU = 2 -NUM_THERMAL = 10 -NUM_SFP = 32 -NUM_COMPONENT = 5 - -IPMI_OEM_NETFN = "0x3A" -IPMI_GET_REBOOT_CAUSE = "0x03 0x00 0x01 0x06" - - -class Chassis(ChassisBase): - """Platform-specific Chassis class""" - - def __init__(self): - self.config_data = {} - ChassisBase.__init__(self) - self._eeprom = Tlv() - self._api_helper = APIHelper() - - for fant_index in range(0, NUM_FAN_TRAY): - for fan_index in range(0, NUM_FAN): - fan = Fan(fant_index, fan_index) - self._fan_list.append(fan) - - for index in range(0, NUM_SFP): - sfp = Sfp(index) - self._sfp_list.append(sfp) - - for index in range(0, NUM_PSU): - psu = Psu(index) - self._psu_list.append(psu) - for index in range(0, NUM_COMPONENT): - component = Component(index) - self._component_list.append(component) - for index in range(0, NUM_THERMAL): - thermal = Thermal(index) - self._thermal_list.append(thermal) - - 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' - """ - return self._eeprom.get_mac() - - def get_serial(self): - """ - Retrieves the hardware serial number for the chassis - Returns: - A string containing the hardware serial number for this chassis. - """ - return self._eeprom.get_serial() - - def get_system_eeprom_info(self): - """ - Retrieves the full content of system EEPROM information for the chassis - Returns: - A dictionary where keys are the type code defined in - OCP ONIE TlvInfo EEPROM format and values are their corresponding - values. - """ - return self._eeprom.get_eeprom() - - def get_reboot_cause(self): - """ - Retrieves the cause of the previous reboot - - Returns: - A tuple (string, string) where the first element is a string - containing the cause of the previous reboot. This string must be - one of the predefined strings in this class. If the first string - is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used - to pass a description of the reboot cause. - """ - - status, raw_cause = self._api_helper.ipmi_raw( - IPMI_OEM_NETFN, IPMI_GET_REBOOT_CAUSE) - hx_cause = raw_cause.split()[0] if status and len( - raw_cause.split()) > 0 else 00 - reboot_cause = { - "00": self.REBOOT_CAUSE_HARDWARE_OTHER, - "11": self.REBOOT_CAUSE_POWER_LOSS, - "22": self.REBOOT_CAUSE_NON_HARDWARE, - "33": self.REBOOT_CAUSE_HARDWARE_OTHER, - "44": self.REBOOT_CAUSE_NON_HARDWARE, - "55": self.REBOOT_CAUSE_NON_HARDWARE, - "66": self.REBOOT_CAUSE_WATCHDOG, - "77": self.REBOOT_CAUSE_NON_HARDWARE - }.get(hx_cause, self.REBOOT_CAUSE_HARDWARE_OTHER) - - description = { - "00": "Unknown reason", - "11": "The last reset is Power on reset", - "22": "The last reset is soft-set CPU warm reset", - "33": "The last reset is soft-set CPU cold reset", - "44": "The last reset is CPU warm reset", - "55": "The last reset is CPU cold reset", - "66": "The last reset is watchdog reset", - "77": "The last reset is power cycle reset" - }.get(hx_cause, "Unknown reason") - - return (reboot_cause, description) diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py deleted file mode 100644 index ba7742c66b..0000000000 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/component.py +++ /dev/null @@ -1,118 +0,0 @@ -############################################################################# -# Celestica -# -# Component contains an implementation of SONiC Platform Base API and -# provides the components firmware management function -# -############################################################################# - -import os.path - -try: - from sonic_platform_base.component_base import ComponentBase - from .helper import APIHelper -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -COMPONENT_LIST = [ - ("BIOS", "Basic Input/Output System"), - ("BMC", "Baseboard Management Controller"), - ("SWITCH_CPLD", "Switch board CPLD"), - ("BASE_CPLD", "Base board CPLD"), - ("FPGA", "Field-programmable gate array") -] -SW_CPLD_VER_PATH = "/sys/module/switch_cpld/version" -BASE_CPLD_VER_PATH = "/sys/module/baseboard_lpc/version" -BIOS_VER_PATH = "/sys/class/dmi/id/bios_version" -BMC_VER_CMD1 = ["ipmitool", "mc", "info"] -BMC_VER_CMD2 = ["grep", "Firmware Revision"] -CFUFLASH_FW_UPGRADE_CMD = ["CFUFLASH", "-cd", "-d", "", "-mse", "3", ""] -MEM_PCI_RESOURCE = "/sys/bus/pci/devices/0000:09:00.0/resource0" -FPGA_VER_MEM_OFFSET = 0 -UPGRADE_OPT = { - 'BMC': '1', - 'BIOS': '2', - 'SWITCH_CPLD': '4', - 'BASE_CPLD': '4' -} - - -class Component(ComponentBase): - """Platform-specific Component class""" - - DEVICE_TYPE = "component" - - def __init__(self, component_index): - ComponentBase.__init__(self) - self.index = component_index - self.name = self.get_name() - self._api_helper = APIHelper() - - def __get_bmc_ver(self): - bmc_ver = "Unknown" - status, raw_bmc_data = self._api_helper.run_command(BMC_VER_CMD1, BMC_VER_CMD2) - if status: - bmc_ver_data = raw_bmc_data.split(":") - bmc_ver = bmc_ver_data[-1].strip() if len( - bmc_ver_data) > 1 else bmc_ver - return bmc_ver - - def __get_fpga_ver(self): - fpga_ver = "Unknown" - status, reg_val = self._api_helper.pci_get_value( - MEM_PCI_RESOURCE, FPGA_VER_MEM_OFFSET) - if status: - major = reg_val[0] >> 16 - minor = int(bin(reg_val[0])[16:32], 2) - fpga_ver = '{}.{}'.format(major, minor) - return fpga_ver - - def get_name(self): - """ - Retrieves the name of the component - Returns: - A string containing the name of the component - """ - return COMPONENT_LIST[self.index][0] - - def get_description(self): - """ - Retrieves the description of the component - Returns: - A string containing the description of the component - """ - return COMPONENT_LIST[self.index][1] - - def get_firmware_version(self): - """ - Retrieves the firmware version of module - Returns: - string: The firmware versions of the module - """ - fw_version = { - "BIOS": self._api_helper.read_txt_file(BIOS_VER_PATH), - "BMC": self.__get_bmc_ver(), - "FPGA": self.__get_fpga_ver(), - "SWITCH_CPLD": self._api_helper.read_txt_file(SW_CPLD_VER_PATH), - "BASE_CPLD": self._api_helper.read_txt_file(BASE_CPLD_VER_PATH), - }.get(self.name, "Unknown") - - return fw_version - - def install_firmware(self, image_path): - """ - Install firmware to module - Args: - image_path: A string, path to firmware image - Returns: - A boolean, True if install successfully, False if not - """ - CFUFLASH_FW_UPGRADE_CMD[3] = UPGRADE_OPT.get(self.name) - CFUFLASH_FW_UPGRADE_CMD[6] = image_path - - if not os.path.isfile(image_path): - return False - - # print(install_command) - status = self._api_helper.run_interactive_command(CFUFLASH_FW_UPGRADE_CMD) - return status diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py deleted file mode 100644 index cf3f1a98de..0000000000 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/eeprom.py +++ /dev/null @@ -1,117 +0,0 @@ -############################################################################# -# Celestica Silverstone -# -# Platform and model specific eeprom subclass, inherits from the base class, -# and provides the followings: -# - the eeprom format definition -# - specific encoder/decoder if there is special need -############################################################################# - -try: - import glob - import os - import sys - import re - from array import array - - if sys.version_info.major == 3: - from io import StringIO - else: - from cStringIO import StringIO - - from sonic_platform_base.sonic_eeprom import eeprom_dts - from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -CACHE_ROOT = '/var/cache/sonic/decode-syseeprom' -CACHE_FILE = 'syseeprom_cache' -TLV_EEPROM_I2C_BUS = 0 -TLV_EEPROM_I2C_ADDR = 56 - - -class Tlv(eeprom_tlvinfo.TlvInfoDecoder): - - EEPROM_DECODE_HEADLINES = 6 - - def __init__(self): - self._eeprom_path = "/sys/class/i2c-adapter/i2c-{0}/{0}-00{1}/eeprom".format( - TLV_EEPROM_I2C_BUS, TLV_EEPROM_I2C_ADDR) - super(Tlv, self).__init__(self._eeprom_path, 0, '', True) - self._eeprom = self._load_eeprom() - - def __parse_output(self, decode_output): - decode_output.replace('\0', '') - lines = decode_output.split('\n') - lines = lines[self.EEPROM_DECODE_HEADLINES:] - _eeprom_info_dict = dict() - - for line in lines: - try: - match = re.search( - '(0x[0-9a-fA-F]{2})([\s]+[\S]+[\s]+)([\S]+)', line) - if match is not None: - idx = match.group(1) - value = match.group(3).rstrip('\0') - - _eeprom_info_dict[idx] = value - except: - pass - return _eeprom_info_dict - - def _load_eeprom(self): - original_stdout = sys.stdout - sys.stdout = StringIO() - try: - self.read_eeprom_db() - except: - decode_output = sys.stdout.getvalue() - sys.stdout = original_stdout - return self.__parse_output(decode_output) - - status = self.check_status() - if 'ok' not in status: - return False - - if not os.path.exists(CACHE_ROOT): - try: - os.makedirs(CACHE_ROOT) - except: - pass - - # - # only the eeprom classes that inherit from eeprom_base - # support caching. Others will work normally - # - try: - self.set_cache_name(os.path.join(CACHE_ROOT, CACHE_FILE)) - except: - pass - - e = self.read_eeprom() - if e is None: - return 0 - - try: - self.update_cache(e) - except: - pass - - self.decode_eeprom(e) - decode_output = sys.stdout.getvalue() - sys.stdout = original_stdout - - (is_valid, valid_crc) = self.is_checksum_valid(e) - if not is_valid: - return False - - return self.__parse_output(decode_output) - - def get_eeprom(self): - return self._eeprom - - def get_serial(self): - return self._eeprom.get('0x23', "Undefined.") - - def get_mac(self): - return self._eeprom.get('0x24', "Undefined.") diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py deleted file mode 100644 index d53de841ee..0000000000 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/helper.py +++ /dev/null @@ -1,111 +0,0 @@ -import os -import struct -import subprocess -from mmap import * -from sonic_py_common.general import check_output_pipe - -HOST_CHK_CMD = ["docker"] -EMPTY_STRING = "" - - -class APIHelper(): - - def __init__(self): - pass - - def is_host(self): - try: - subprocess.call(HOST_CHK_CMD, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - except FileNotFoundError: - return False - return True - - def pci_get_value(self, resource, offset): - status = True - result = "" - try: - fd = os.open(resource, os.O_RDWR) - mm = mmap(fd, 0) - mm.seek(int(offset)) - read_data_stream = mm.read(4) - result = struct.unpack('I', read_data_stream) - except: - status = False - return status, result - - def run_command(self, cmd1_args, cmd2_args): - status = True - result = "" - try: - result = check_output_pipe(cmd1_args, cmd2_args) - except subprocess.CalledProcessError: - status = False - return status, result - - def run_interactive_command(self, cmd): - try: - subprocess.call(cmd) - except: - return False - return True - - def read_txt_file(self, file_path): - try: - with open(file_path, 'r') as fd: - data = fd.read() - return data.strip() - except IOError: - pass - return None - - def ipmi_raw(self, netfn, cmd): - status = True - result = "" - try: - cmd = ["ipmitool", "raw", str(netfn), str(cmd)] - p = subprocess.Popen( - cmd, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - raw_data, err = p.communicate() - if err == '': - result = raw_data.strip() - else: - status = False - except: - status = False - return status, result - - def ipmi_fru_id(self, id, key=None): - status = True - result = "" - cmd1_args = ["ipmitool", "fru", "print", str(id)] - if not key: - try: - p = subprocess.Popen( - cmd1_args, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - raw_data, err = p.communicate() - if err == '': - result = raw_data.strip() - else: - status = False - except: - status = False - else: - cmd2_args = ["grep", str(key)] - status, result = self.run_command(cmd1_args, cmd2_args) - return status, result - - def ipmi_set_ss_thres(self, id, threshold_key, value): - status = True - result = "" - try: - cmd = ["ipmitool", "sensor", "thresh", str(id), str(threshold_key), str(value)] - p = subprocess.Popen( - cmd, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - raw_data, err = p.communicate() - if err == '': - result = raw_data.strip() - else: - status = False - except: - status = False - return status, result diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py deleted file mode 100644 index a6c805d3ca..0000000000 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/psu.py +++ /dev/null @@ -1,236 +0,0 @@ -############################################################################# -# Celestica -# -# Module contains an implementation of SONiC Platform Base API and -# provides the PSUs status which are available in the platform -# -############################################################################# - -import os -import re -import math -import sonic_platform - -try: - from sonic_platform_base.psu_base import PsuBase - from .helper import APIHelper - from sonic_platform.fan import Fan -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -PSU_NAME_LIST = ["PSU-1", "PSU-2"] -PSU_NUM_FAN = [1, 1] - -IPMI_SENSOR_NETFN = "0x04" -IPMI_OEM_NETFN = "0x3A" -IPMI_SS_READ_CMD = "0x2D {}" -IPMI_SET_PSU_LED_CMD = "0x07 0x02 {}" -IPMI_GET_PSU_LED_CMD = "0x08 0x02" -IPMI_FRU_MODEL_KEY = "Board Part Number" -IPMI_FRU_SERIAL_KEY = "Board Serial" - -PSU_LED_OFF_CMD = "0x00" -PSU_LED_GREEN_CMD = "0x01" -PSU_LED_AMBER_CMD = "0x02" - -PSU1_FRU_ID = 3 - -SS_READ_OFFSET = 0 - -PSU_VOUT_SS_ID = ["0x36", "0x40"] -PSU_COUT_SS_ID = ["0x37", "0x41"] -PSU_POUT_SS_ID = ["0x38", "0x42"] -PSU_STATUS_REG = ["0x39", "0x2f"] - - -class Psu(PsuBase): - """Platform-specific Psu class""" - - def __init__(self, psu_index): - PsuBase.__init__(self) - self.index = psu_index - for fan_index in range(0, PSU_NUM_FAN[self.index]): - fan = Fan(fan_index, 0, is_psu_fan=True, psu_index=self.index) - self._fan_list.append(fan) - self._api_helper = APIHelper() - - def find_value(self, in_string): - result = re.search("^.+ ([0-9a-f]{2}) .+$", in_string) - return result.group(1) if result else result - - def get_voltage(self): - """ - Retrieves current PSU voltage output - Returns: - A float number, the output voltage in volts, - e.g. 12.1 - """ - psu_voltage = 0.0 - psu_vout_key = PSU_VOUT_SS_ID[self.index] - status, raw_ss_read = self._api_helper.ipmi_raw( - IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_vout_key)) - ss_read = raw_ss_read.split()[SS_READ_OFFSET] - # Formula: Rx1x10^-1 - psu_voltage = int(ss_read, 16) * math.pow(10, -1) - - return psu_voltage - - def get_current(self): - """ - Retrieves present electric current supplied by PSU - Returns: - A float number, the electric current in amperes, e.g 15.4 - """ - psu_current = 0.0 - psu_cout_key = PSU_COUT_SS_ID[self.index] - status, raw_ss_read = self._api_helper.ipmi_raw( - IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_cout_key)) - ss_read = raw_ss_read.split()[SS_READ_OFFSET] - # Formula: Rx5x10^-1 - psu_current = int(ss_read, 16) * 5 * math.pow(10, -1) - - return psu_current - - def get_power(self): - """ - Retrieves current energy supplied by PSU - Returns: - A float number, the power in watts, e.g. 302.6 - """ - psu_power = 0.0 - psu_pout_key = PSU_POUT_SS_ID[self.index] - status, raw_ss_read = self._api_helper.ipmi_raw( - IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pout_key)) - ss_read = raw_ss_read.split()[SS_READ_OFFSET] - # Formula: Rx6x10^0 - psu_power = int(ss_read, 16) * 6 - return psu_power - - def get_powergood_status(self): - """ - Retrieves the powergood status of PSU - Returns: - A boolean, True if PSU has stablized its output voltages and passed all - its internal self-tests, False if not. - """ - return self.get_status() - - def set_status_led(self, color): - """ - Sets the state of the PSU status LED - Args: - color: A string representing the color with which to set the PSU status LED - Note: Only support green and off - Returns: - bool: True if status LED state is set successfully, False if not - Note - Set manual - ipmitool raw 0x3a 0x09 0x2 0x0 - """ - led_cmd = { - self.STATUS_LED_COLOR_GREEN: PSU_LED_GREEN_CMD, - self.STATUS_LED_COLOR_AMBER: PSU_LED_AMBER_CMD, - self.STATUS_LED_COLOR_OFF: PSU_LED_OFF_CMD - }.get(color) - - status, set_led = self._api_helper.ipmi_raw( - IPMI_OEM_NETFN, IPMI_SET_PSU_LED_CMD.format(led_cmd)) - set_status_led = False if not status else True - - return set_status_led - - def get_status_led(self): - """ - Gets the state of the PSU status LED - Returns: - A string, one of the predefined STATUS_LED_COLOR_* strings above - """ - status, hx_color = self._api_helper.ipmi_raw( - IPMI_OEM_NETFN, IPMI_GET_PSU_LED_CMD) - - status_led = { - "00": self.STATUS_LED_COLOR_OFF, - "01": self.STATUS_LED_COLOR_GREEN, - "02": self.STATUS_LED_COLOR_AMBER, - }.get(hx_color, self.STATUS_LED_COLOR_OFF) - - return status_led - - def get_name(self): - """ - Retrieves the name of the device - Returns: - string: The name of the device - """ - return PSU_NAME_LIST[self.index] - - def get_presence(self): - """ - Retrieves the presence of the PSU - Returns: - bool: True if PSU is present, False if not - """ - psu_presence = False - psu_pstatus_key = PSU_STATUS_REG[self.index] - status, raw_status_read = self._api_helper.ipmi_raw( - IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pstatus_key)) - status_byte = self.find_value(raw_status_read) - - if status: - presence_int = (int(status_byte, 16) >> 0) & 1 - psu_presence = True if presence_int else False - - return psu_presence - - def get_model(self): - """ - Retrieves the model number (or part number) of the device - Returns: - string: Model/part number of device - """ - model = "Unknown" - ipmi_fru_idx = self.index + PSU1_FRU_ID - status, raw_model = self._api_helper.ipmi_fru_id( - ipmi_fru_idx, IPMI_FRU_MODEL_KEY) - - fru_pn_list = raw_model.split() - if len(fru_pn_list) > 4: - model = fru_pn_list[4] - - return model - - def get_serial(self): - """ - Retrieves the serial number of the device - Returns: - string: Serial number of device - """ - serial = "Unknown" - ipmi_fru_idx = self.index + PSU1_FRU_ID - status, raw_model = self._api_helper.ipmi_fru_id( - ipmi_fru_idx, IPMI_FRU_SERIAL_KEY) - - fru_sr_list = raw_model.split() - if len(fru_sr_list) > 3: - serial = fru_sr_list[3] - - return serial - - def get_status(self): - """ - Retrieves the operational status of the device - Returns: - A boolean value, True if device is operating properly, False if not - """ - psu_status = False - psu_pstatus_key = PSU_STATUS_REG[self.index] - status, raw_status_read = self._api_helper.ipmi_raw( - IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(psu_pstatus_key)) - status_byte = self.find_value(raw_status_read) - - if status: - failure_detected = (int(status_byte, 16) >> 1) & 1 - input_lost = (int(status_byte, 16) >> 3) & 1 - psu_status = False if (input_lost or failure_detected) else True - - return psu_status diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py b/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py deleted file mode 100644 index 4ad97b42ff..0000000000 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/sfp.py +++ /dev/null @@ -1,1467 +0,0 @@ -############################################################################# -# Celestica -# -# Sfp contains an implementation of SONiC Platform Base API and -# provides the sfp device status which are available in the platform -# -############################################################################# - -import time -import subprocess -from ctypes import create_string_buffer - -try: - from sonic_platform_base.sfp_base import SfpBase - from sonic_platform_base.sonic_eeprom import eeprom_dts - from sonic_platform_base.sonic_sfp.sff8472 import sff8472InterfaceId - from sonic_platform_base.sonic_sfp.sff8472 import sff8472Dom - from sonic_platform_base.sonic_sfp.sff8436 import sff8436InterfaceId - from sonic_platform_base.sonic_sfp.sff8436 import sff8436Dom - from sonic_platform_base.sonic_sfp.inf8628 import inf8628InterfaceId - from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - -INFO_OFFSET = 128 -DOM_OFFSET = 0 - -# definitions of the offset and width for values in XCVR info eeprom -XCVR_INTFACE_BULK_OFFSET = 0 -XCVR_INTFACE_BULK_WIDTH_QSFP = 20 -XCVR_INTFACE_BULK_WIDTH_SFP = 21 -XCVR_TYPE_OFFSET = 0 -XCVR_TYPE_WIDTH = 1 -XCVR_EXT_TYPE_OFFSET = 1 -XCVR_EXT_TYPE_WIDTH = 1 -XCVR_CONNECTOR_OFFSET = 2 -XCVR_CONNECTOR_WIDTH = 1 -XCVR_COMPLIANCE_CODE_OFFSET = 3 -XCVR_COMPLIANCE_CODE_WIDTH = 8 -XCVR_ENCODING_OFFSET = 11 -XCVR_ENCODING_WIDTH = 1 -XCVR_NBR_OFFSET = 12 -XCVR_NBR_WIDTH = 1 -XCVR_EXT_RATE_SEL_OFFSET = 13 -XCVR_EXT_RATE_SEL_WIDTH = 1 -XCVR_CABLE_LENGTH_OFFSET = 14 -XCVR_CABLE_LENGTH_WIDTH_QSFP = 5 -XCVR_CABLE_LENGTH_WIDTH_SFP = 6 -XCVR_VENDOR_NAME_OFFSET = 20 -XCVR_VENDOR_NAME_WIDTH = 16 -XCVR_VENDOR_OUI_OFFSET = 37 -XCVR_VENDOR_OUI_WIDTH = 3 -XCVR_VENDOR_PN_OFFSET = 40 -XCVR_VENDOR_PN_WIDTH = 16 -XCVR_HW_REV_OFFSET = 56 -XCVR_HW_REV_WIDTH_OSFP = 2 -XCVR_HW_REV_WIDTH_QSFP = 2 -XCVR_HW_REV_WIDTH_SFP = 4 -XCVR_VENDOR_SN_OFFSET = 68 -XCVR_VENDOR_SN_WIDTH = 16 -XCVR_VENDOR_DATE_OFFSET = 84 -XCVR_VENDOR_DATE_WIDTH = 8 -XCVR_DOM_CAPABILITY_OFFSET = 92 -XCVR_DOM_CAPABILITY_WIDTH = 2 - -XCVR_INTERFACE_DATA_START = 0 -XCVR_INTERFACE_DATA_SIZE = 92 - -QSFP_DOM_BULK_DATA_START = 22 -QSFP_DOM_BULK_DATA_SIZE = 36 -SFP_DOM_BULK_DATA_START = 96 -SFP_DOM_BULK_DATA_SIZE = 10 - -# definitions of the offset for values in OSFP info eeprom -OSFP_TYPE_OFFSET = 0 -OSFP_VENDOR_NAME_OFFSET = 129 -OSFP_VENDOR_PN_OFFSET = 148 -OSFP_HW_REV_OFFSET = 164 -OSFP_VENDOR_SN_OFFSET = 166 - -# Offset for values in QSFP eeprom -QSFP_DOM_REV_OFFSET = 1 -QSFP_DOM_REV_WIDTH = 1 -QSFP_TEMPE_OFFSET = 22 -QSFP_TEMPE_WIDTH = 2 -QSFP_VOLT_OFFSET = 26 -QSFP_VOLT_WIDTH = 2 -QSFP_VERSION_COMPLIANCE_OFFSET = 1 -QSFP_VERSION_COMPLIANCE_WIDTH = 2 -QSFP_CHANNL_MON_OFFSET = 34 -QSFP_CHANNL_MON_WIDTH = 16 -QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH = 24 -QSFP_CHANNL_DISABLE_STATUS_OFFSET = 86 -QSFP_CHANNL_DISABLE_STATUS_WIDTH = 1 -QSFP_CHANNL_RX_LOS_STATUS_OFFSET = 3 -QSFP_CHANNL_RX_LOS_STATUS_WIDTH = 1 -QSFP_CHANNL_TX_FAULT_STATUS_OFFSET = 4 -QSFP_CHANNL_TX_FAULT_STATUS_WIDTH = 1 -QSFP_CONTROL_OFFSET = 86 -QSFP_CONTROL_WIDTH = 8 -QSFP_MODULE_MONITOR_OFFSET = 0 -QSFP_MODULE_MONITOR_WIDTH = 9 -QSFP_POWEROVERRIDE_OFFSET = 93 -QSFP_POWEROVERRIDE_WIDTH = 1 -QSFP_POWEROVERRIDE_BIT = 0 -QSFP_POWERSET_BIT = 1 -QSFP_OPTION_VALUE_OFFSET = 192 -QSFP_OPTION_VALUE_WIDTH = 4 -QSFP_MODULE_UPPER_PAGE3_START = 384 -QSFP_MODULE_THRESHOLD_OFFSET = 128 -QSFP_MODULE_THRESHOLD_WIDTH = 24 -QSFP_CHANNL_THRESHOLD_OFFSET = 176 -QSFP_CHANNL_THRESHOLD_WIDTH = 24 - -SFP_MODULE_ADDRA2_OFFSET = 256 -SFP_MODULE_THRESHOLD_OFFSET = 0 -SFP_MODULE_THRESHOLD_WIDTH = 56 -SFP_CHANNL_THRESHOLD_OFFSET = 112 -SFP_CHANNL_THRESHOLD_WIDTH = 2 - -SFP_TEMPE_OFFSET = 96 -SFP_TEMPE_WIDTH = 2 -SFP_VOLT_OFFSET = 98 -SFP_VOLT_WIDTH = 2 -SFP_CHANNL_MON_OFFSET = 100 -SFP_CHANNL_MON_WIDTH = 6 -SFP_CHANNL_STATUS_OFFSET = 110 -SFP_CHANNL_STATUS_WIDTH = 1 - - -qsfp_cable_length_tup = ('Length(km)', 'Length OM3(2m)', - 'Length OM2(m)', 'Length OM1(m)', - 'Length Cable Assembly(m)') - -sfp_cable_length_tup = ('LengthSMFkm-UnitsOfKm', 'LengthSMF(UnitsOf100m)', - 'Length50um(UnitsOf10m)', 'Length62.5um(UnitsOfm)', - 'LengthCable(UnitsOfm)', 'LengthOM3(UnitsOf10m)') - -sfp_compliance_code_tup = ('10GEthernetComplianceCode', 'InfinibandComplianceCode', - 'ESCONComplianceCodes', 'SONETComplianceCodes', - 'EthernetComplianceCodes', 'FibreChannelLinkLength', - 'FibreChannelTechnology', 'SFP+CableTechnology', - 'FibreChannelTransmissionMedia', 'FibreChannelSpeed') - -qsfp_compliance_code_tup = ('10/40G Ethernet Compliance Code', 'SONET Compliance codes', - 'SAS/SATA compliance codes', 'Gigabit Ethernet Compliant codes', - 'Fibre Channel link length/Transmitter Technology', - 'Fibre Channel transmission media', 'Fibre Channel Speed') - -SFP_TYPE = "SFP" -QSFP_TYPE = "QSFP" -OSFP_TYPE = "OSFP" - -PORT_START = 1 -PORT_END = 34 -OSFP_PORT_START = 1 -OSFP_PORT_END = 32 -SFP_PORT_START = 33 -SFP_PORT_END = 34 - -PORT_INFO_PATH = '/sys/devices/platform/cls-xcvr' - - -class Sfp(SfpBase): - """Platform-specific Sfp class""" - - # Path to QSFP sysfs - PLATFORM_ROOT_PATH = "/usr/share/sonic/device" - PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" - HOST_CHK_CMD = ["docker"] - - PLATFORM = "x86_64-cel_silverstone-r0" - HWSKU = "Silverstone" - - def __init__(self, sfp_index): - SfpBase.__init__(self) - # Init index - self.index = sfp_index - self.port_num = self.index + 1 - self.dom_supported = False - self.sfp_type, self.port_name = self.__get_sfp_info() - - # Init eeprom path - eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' - self.port_to_eeprom_mapping = {} - self.port_to_i2c_mapping = { - 1: 10, - 2: 11, - 3: 12, - 4: 13, - 5: 14, - 6: 15, - 7: 16, - 8: 17, - 9: 18, - 10: 19, - 11: 20, - 12: 21, - 13: 22, - 14: 23, - 15: 24, - 16: 25, - 17: 26, - 18: 27, - 19: 28, - 20: 29, - 21: 30, - 22: 31, - 23: 32, - 24: 33, - 25: 34, - 26: 35, - 27: 36, - 28: 37, - 29: 38, - 30: 39, - 31: 40, - 32: 41, - 33: 1, - 34: 2 - } - - for x in range(PORT_START, PORT_END + 1): - port_eeprom_path = eeprom_path.format(self.port_to_i2c_mapping[x]) - self.port_to_eeprom_mapping[x] = port_eeprom_path - - self.info_dict_keys = ['type', 'vendor_rev', 'serial', 'manufacturer', 'model', 'connector', 'encoding', 'ext_identifier', - 'ext_rateselect_compliance', 'cable_type', 'cable_length', 'nominal_bit_rate', 'specification_compliance', 'vendor_date', 'vendor_oui'] - - self.dom_dict_keys = ['rx_los', 'tx_fault', 'reset_status', 'power_lpmode', 'tx_disable', 'tx_disable_channel', 'temperature', 'voltage', - 'rx1power', 'rx2power', 'rx3power', 'rx4power', 'tx1bias', 'tx2bias', 'tx3bias', 'tx4bias', 'tx1power', 'tx2power', 'tx3power', 'tx4power'] - - self.threshold_dict_keys = ['temphighalarm', 'temphighwarning', 'templowalarm', 'templowwarning', 'vcchighalarm', 'vcchighwarning', 'vcclowalarm', 'vcclowwarning', 'rxpowerhighalarm', 'rxpowerhighwarning', - 'rxpowerlowalarm', 'rxpowerlowwarning', 'txpowerhighalarm', 'txpowerhighwarning', 'txpowerlowalarm', 'txpowerlowwarning', 'txbiashighalarm', 'txbiashighwarning', 'txbiaslowalarm', 'txbiaslowwarning'] - - self._dom_capability_detect() - - def __get_sfp_info(self): - port_num = self.index + PORT_START - sfp_type = OSFP_PORT_START - port_name = "Unknown" - - if port_num >= OSFP_PORT_START and port_num <= OSFP_PORT_END: - sfp_type = OSFP_TYPE - port_name = "QSFP" + str(port_num - OSFP_PORT_START + 1) - elif port_num >= SFP_PORT_START and port_num <= SFP_PORT_END: - sfp_type = SFP_TYPE - port_name = "SFP" + str(port_num - SFP_PORT_START + 1) - return sfp_type, port_name - - def __convert_string_to_num(self, value_str): - if "-inf" in value_str: - return 'N/A' - elif "Unknown" in value_str: - return 'N/A' - elif 'dBm' in value_str: - t_str = value_str.rstrip('dBm') - return float(t_str) - elif 'mA' in value_str: - t_str = value_str.rstrip('mA') - return float(t_str) - elif 'C' in value_str: - t_str = value_str.rstrip('C') - return float(t_str) - elif 'Volts' in value_str: - t_str = value_str.rstrip('Volts') - return float(t_str) - else: - return 'N/A' - - def __is_host(self): - try: - subprocess.call(self.HOST_CHK_CMD, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) - except FileNotFoundError: - return False - return True - - def __get_path_to_port_config_file(self): - platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.PLATFORM]) - hwsku_path = "/".join([platform_path, self.HWSKU] - ) if self.__is_host() else self.PMON_HWSKU_PATH - return "/".join([hwsku_path, "port_config.ini"]) - - def __read_eeprom_specific_bytes(self, offset, num_bytes): - sysfsfile_eeprom = None - eeprom_raw = [] - for i in range(0, num_bytes): - eeprom_raw.append("0x00") - - sysfs_sfp_i2c_client_eeprom_path = self.port_to_eeprom_mapping[self.port_num] - try: - sysfsfile_eeprom = open( - sysfs_sfp_i2c_client_eeprom_path, mode="rb", buffering=0) - sysfsfile_eeprom.seek(offset) - raw = sysfsfile_eeprom.read(num_bytes) - for n in range(0, num_bytes): - eeprom_raw[n] = hex(ord(raw[n]))[2:].zfill(2) - except: - pass - finally: - if sysfsfile_eeprom: - sysfsfile_eeprom.close() - - return eeprom_raw - - def _dom_capability_detect(self): - if not self.get_presence(): - self.dom_supported = False - self.dom_temp_supported = False - self.dom_volt_supported = False - self.dom_rx_power_supported = False - self.dom_tx_power_supported = False - self.calibration = 0 - return - - if self.sfp_type == "QSFP": - self.calibration = 1 - sfpi_obj = sff8436InterfaceId() - if sfpi_obj is None: - self.dom_supported = False - offset = 128 - - # QSFP capability byte parse, through this byte can know whether it support tx_power or not. - # TODO: in the future when decided to migrate to support SFF-8636 instead of SFF-8436, - # need to add more code for determining the capability and version compliance - # in SFF-8636 dom capability definitions evolving with the versions. - qsfp_dom_capability_raw = self.__read_eeprom_specific_bytes( - (offset + XCVR_DOM_CAPABILITY_OFFSET), XCVR_DOM_CAPABILITY_WIDTH) - if qsfp_dom_capability_raw is not None: - qsfp_version_compliance_raw = self.__read_eeprom_specific_bytes( - QSFP_VERSION_COMPLIANCE_OFFSET, QSFP_VERSION_COMPLIANCE_WIDTH) - qsfp_version_compliance = int( - qsfp_version_compliance_raw[0], 16) - dom_capability = sfpi_obj.parse_dom_capability( - qsfp_dom_capability_raw, 0) - if qsfp_version_compliance >= 0x08: - self.dom_temp_supported = dom_capability['data']['Temp_support']['value'] == 'On' - self.dom_volt_supported = dom_capability['data']['Voltage_support']['value'] == 'On' - self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' - self.dom_tx_power_supported = dom_capability['data']['Tx_power_support']['value'] == 'On' - else: - self.dom_temp_supported = True - self.dom_volt_supported = True - self.dom_rx_power_supported = dom_capability['data']['Rx_power_support']['value'] == 'On' - self.dom_tx_power_supported = True - - self.dom_supported = True - self.calibration = 1 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return None - qsfp_option_value_raw = self.__read_eeprom_specific_bytes( - QSFP_OPTION_VALUE_OFFSET, QSFP_OPTION_VALUE_WIDTH) - if qsfp_option_value_raw is not None: - optional_capability = sfpd_obj.parse_option_params( - qsfp_option_value_raw, 0) - self.dom_tx_disable_supported = optional_capability[ - 'data']['TxDisable']['value'] == 'On' - dom_status_indicator = sfpd_obj.parse_dom_status_indicator( - qsfp_version_compliance_raw, 1) - self.qsfp_page3_available = dom_status_indicator['data']['FlatMem']['value'] == 'Off' - else: - self.dom_supported = False - self.dom_temp_supported = False - self.dom_volt_supported = False - self.dom_rx_power_supported = False - self.dom_tx_power_supported = False - self.calibration = 0 - self.qsfp_page3_available = False - - elif self.sfp_type == "SFP": - sfpi_obj = sff8472InterfaceId() - if sfpi_obj is None: - return None - sfp_dom_capability_raw = self.__read_eeprom_specific_bytes( - XCVR_DOM_CAPABILITY_OFFSET, XCVR_DOM_CAPABILITY_WIDTH) - if sfp_dom_capability_raw is not None: - sfp_dom_capability = int(sfp_dom_capability_raw[0], 16) - self.dom_supported = (sfp_dom_capability & 0x40 != 0) - if self.dom_supported: - self.dom_temp_supported = True - self.dom_volt_supported = True - self.dom_rx_power_supported = True - self.dom_tx_power_supported = True - if sfp_dom_capability & 0x20 != 0: - self.calibration = 1 - elif sfp_dom_capability & 0x10 != 0: - self.calibration = 2 - else: - self.calibration = 0 - else: - self.dom_temp_supported = False - self.dom_volt_supported = False - self.dom_rx_power_supported = False - self.dom_tx_power_supported = False - self.calibration = 0 - self.dom_tx_disable_supported = ( - int(sfp_dom_capability_raw[1], 16) & 0x40 != 0) - else: - self.dom_supported = False - self.dom_temp_supported = False - self.dom_volt_supported = False - self.dom_rx_power_supported = False - self.dom_tx_power_supported = False - - def get_transceiver_info(self): - """ - Retrieves transceiver info of this SFP - Returns: - A dict which contains following keys/values : - ======================================================================== - keys |Value Format |Information - ---------------------------|---------------|---------------------------- - type |1*255VCHAR |type of SFP - vendor_rev |1*255VCHAR |vendor revision of SFP - serial |1*255VCHAR |serial number of the SFP - manufacturer |1*255VCHAR |SFP vendor name - model |1*255VCHAR |SFP model name - connector |1*255VCHAR |connector information - encoding |1*255VCHAR |encoding information - ext_identifier |1*255VCHAR |extend identifier - ext_rateselect_compliance |1*255VCHAR |extended rateSelect compliance - cable_length |INT |cable length in m - nominal_bit_rate |INT |nominal bit rate by 100Mbs - specification_compliance |1*255VCHAR |specification compliance - vendor_date |1*255VCHAR |vendor date - vendor_oui |1*255VCHAR |vendor OUI - ======================================================================== - """ - compliance_code_dict = {} - transceiver_info_dict = dict.fromkeys(self.info_dict_keys, 'N/A') - if not self.get_presence(): - return transceiver_info_dict - - # ToDo: OSFP tranceiver info parsing not fully supported. - # in inf8628.py lack of some memory map definition - # will be implemented when the inf8628 memory map ready - if self.sfp_type == OSFP_TYPE: - offset = 0 - vendor_rev_width = XCVR_HW_REV_WIDTH_OSFP - - sfpi_obj = inf8628InterfaceId() - if sfpi_obj is None: - return None - - sfp_type_raw = self.__read_eeprom_specific_bytes( - (offset + OSFP_TYPE_OFFSET), XCVR_TYPE_WIDTH) - if sfp_type_raw is not None: - sfp_type_data = sfpi_obj.parse_sfp_type(sfp_type_raw, 0) - else: - return None - - sfp_vendor_name_raw = self.__read_eeprom_specific_bytes( - (offset + OSFP_VENDOR_NAME_OFFSET), XCVR_VENDOR_NAME_WIDTH) - if sfp_vendor_name_raw is not None: - sfp_vendor_name_data = sfpi_obj.parse_vendor_name( - sfp_vendor_name_raw, 0) - else: - return None - - sfp_vendor_pn_raw = self.__read_eeprom_specific_bytes( - (offset + OSFP_VENDOR_PN_OFFSET), XCVR_VENDOR_PN_WIDTH) - if sfp_vendor_pn_raw is not None: - sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( - sfp_vendor_pn_raw, 0) - else: - return None - - sfp_vendor_rev_raw = self.__read_eeprom_specific_bytes( - (offset + OSFP_HW_REV_OFFSET), vendor_rev_width) - if sfp_vendor_rev_raw is not None: - sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( - sfp_vendor_rev_raw, 0) - else: - return None - - sfp_vendor_sn_raw = self.__read_eeprom_specific_bytes( - (offset + OSFP_VENDOR_SN_OFFSET), XCVR_VENDOR_SN_WIDTH) - if sfp_vendor_sn_raw is not None: - sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( - sfp_vendor_sn_raw, 0) - else: - return None - - transceiver_info_dict['type'] = sfp_type_data['data']['type']['value'] - transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['vendor_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] - transceiver_info_dict['vendor_oui'] = 'N/A' - transceiver_info_dict['vendor_date'] = 'N/A' - transceiver_info_dict['connector'] = 'N/A' - transceiver_info_dict['encoding'] = 'N/A' - transceiver_info_dict['ext_identifier'] = 'N/A' - transceiver_info_dict['ext_rateselect_compliance'] = 'N/A' - transceiver_info_dict['cable_type'] = 'N/A' - transceiver_info_dict['cable_length'] = 'N/A' - transceiver_info_dict['specification_compliance'] = 'N/A' - transceiver_info_dict['nominal_bit_rate'] = 'N/A' - - else: - if self.sfp_type == QSFP_TYPE: - offset = 128 - vendor_rev_width = XCVR_HW_REV_WIDTH_QSFP - cable_length_width = XCVR_CABLE_LENGTH_WIDTH_QSFP - interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_QSFP - sfp_type = 'QSFP' - - sfpi_obj = sff8436InterfaceId() - if sfpi_obj is None: - print("Error: sfp_object open failed") - return None - - else: - offset = 0 - vendor_rev_width = XCVR_HW_REV_WIDTH_SFP - cable_length_width = XCVR_CABLE_LENGTH_WIDTH_SFP - interface_info_bulk_width = XCVR_INTFACE_BULK_WIDTH_SFP - sfp_type = 'SFP' - - sfpi_obj = sff8472InterfaceId() - if sfpi_obj is None: - print("Error: sfp_object open failed") - return None - sfp_interface_bulk_raw = self.__read_eeprom_specific_bytes( - offset + XCVR_INTERFACE_DATA_START, XCVR_INTERFACE_DATA_SIZE) - if sfp_interface_bulk_raw is None: - return None - - start = XCVR_INTFACE_BULK_OFFSET - XCVR_INTERFACE_DATA_START - end = start + interface_info_bulk_width - sfp_interface_bulk_data = sfpi_obj.parse_sfp_info_bulk( - sfp_interface_bulk_raw[start: end], 0) - - start = XCVR_VENDOR_NAME_OFFSET - XCVR_INTERFACE_DATA_START - end = start + XCVR_VENDOR_NAME_WIDTH - sfp_vendor_name_data = sfpi_obj.parse_vendor_name( - sfp_interface_bulk_raw[start: end], 0) - - start = XCVR_VENDOR_PN_OFFSET - XCVR_INTERFACE_DATA_START - end = start + XCVR_VENDOR_PN_WIDTH - sfp_vendor_pn_data = sfpi_obj.parse_vendor_pn( - sfp_interface_bulk_raw[start: end], 0) - - start = XCVR_HW_REV_OFFSET - XCVR_INTERFACE_DATA_START - end = start + vendor_rev_width - sfp_vendor_rev_data = sfpi_obj.parse_vendor_rev( - sfp_interface_bulk_raw[start: end], 0) - - start = XCVR_VENDOR_SN_OFFSET - XCVR_INTERFACE_DATA_START - end = start + XCVR_VENDOR_SN_WIDTH - sfp_vendor_sn_data = sfpi_obj.parse_vendor_sn( - sfp_interface_bulk_raw[start: end], 0) - - start = XCVR_VENDOR_OUI_OFFSET - XCVR_INTERFACE_DATA_START - end = start + XCVR_VENDOR_OUI_WIDTH - sfp_vendor_oui_data = sfpi_obj.parse_vendor_oui( - sfp_interface_bulk_raw[start: end], 0) - - start = XCVR_VENDOR_DATE_OFFSET - XCVR_INTERFACE_DATA_START - end = start + XCVR_VENDOR_DATE_WIDTH - sfp_vendor_date_data = sfpi_obj.parse_vendor_date( - sfp_interface_bulk_raw[start: end], 0) - transceiver_info_dict['type'] = sfp_interface_bulk_data['data']['type']['value'] - transceiver_info_dict['manufacturer'] = sfp_vendor_name_data['data']['Vendor Name']['value'] - transceiver_info_dict['model'] = sfp_vendor_pn_data['data']['Vendor PN']['value'] - transceiver_info_dict['vendor_rev'] = sfp_vendor_rev_data['data']['Vendor Rev']['value'] - transceiver_info_dict['serial'] = sfp_vendor_sn_data['data']['Vendor SN']['value'] - transceiver_info_dict['vendor_oui'] = sfp_vendor_oui_data['data']['Vendor OUI']['value'] - transceiver_info_dict['vendor_date'] = sfp_vendor_date_data[ - 'data']['VendorDataCode(YYYY-MM-DD Lot)']['value'] - transceiver_info_dict['connector'] = sfp_interface_bulk_data['data']['Connector']['value'] - transceiver_info_dict['encoding'] = sfp_interface_bulk_data['data']['EncodingCodes']['value'] - transceiver_info_dict['ext_identifier'] = sfp_interface_bulk_data['data']['Extended Identifier']['value'] - transceiver_info_dict['ext_rateselect_compliance'] = sfp_interface_bulk_data['data']['RateIdentifier']['value'] - if self.sfp_type == QSFP_TYPE: - for key in qsfp_cable_length_tup: - if key in sfp_interface_bulk_data['data']: - transceiver_info_dict['cable_type'] = key - transceiver_info_dict['cable_length'] = str( - sfp_interface_bulk_data['data'][key]['value']) - - for key in qsfp_compliance_code_tup: - if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: - compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] - transceiver_info_dict['specification_compliance'] = str( - compliance_code_dict) - - transceiver_info_dict['nominal_bit_rate'] = str( - sfp_interface_bulk_data['data']['Nominal Bit Rate(100Mbs)']['value']) - else: - for key in sfp_cable_length_tup: - if key in sfp_interface_bulk_data['data']: - transceiver_info_dict['cable_type'] = key - transceiver_info_dict['cable_length'] = str( - sfp_interface_bulk_data['data'][key]['value']) - - for key in sfp_compliance_code_tup: - if key in sfp_interface_bulk_data['data']['Specification compliance']['value']: - compliance_code_dict[key] = sfp_interface_bulk_data['data']['Specification compliance']['value'][key]['value'] - transceiver_info_dict['specification_compliance'] = str( - compliance_code_dict) - - transceiver_info_dict['nominal_bit_rate'] = str( - sfp_interface_bulk_data['data']['NominalSignallingRate(UnitsOf100Mbd)']['value']) - - return transceiver_info_dict - - def get_transceiver_bulk_status(self): - """ - Retrieves transceiver bulk status of this SFP - Returns: - A dict which contains following keys/values : - ======================================================================== - keys |Value Format |Information - ---------------------------|---------------|---------------------------- - rx_los |BOOLEAN |RX loss-of-signal status, True if has RX los, False if not. - tx_fault |BOOLEAN |TX fault status, True if has TX fault, False if not. - reset_status |BOOLEAN |reset status, True if SFP in reset, False if not. - lp_mode |BOOLEAN |low power mode status, True in lp mode, False if not. - tx_disable |BOOLEAN |TX disable status, True TX disabled, False if not. - tx_disabled_channel |HEX |disabled TX channels in hex, bits 0 to 3 represent channel 0 - | |to channel 3. - temperature |INT |module temperature in Celsius - voltage |INT |supply voltage in mV - txbias |INT |TX Bias Current in mA, n is the channel number, - | |for example, tx2bias stands for tx bias of channel 2. - rxpower |INT |received optical power in mW, n is the channel number, - | |for example, rx2power stands for rx power of channel 2. - txpower |INT |TX output power in mW, n is the channel number, - | |for example, tx2power stands for tx power of channel 2. - ======================================================================== - """ - transceiver_dom_info_dict = dict.fromkeys(self.dom_dict_keys, 'N/A') - - if self.sfp_type == OSFP_TYPE: - pass - - elif self.sfp_type == QSFP_TYPE: - if not self.dom_supported: - return transceiver_dom_info_dict - - offset = 0 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return transceiver_dom_info_dict - - dom_data_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_DOM_BULK_DATA_START), QSFP_DOM_BULK_DATA_SIZE) - if dom_data_raw is None: - return transceiver_dom_info_dict - - if self.dom_temp_supported: - start = QSFP_TEMPE_OFFSET - QSFP_DOM_BULK_DATA_START - end = start + QSFP_TEMPE_WIDTH - dom_temperature_data = sfpd_obj.parse_temperature( - dom_data_raw[start: end], 0) - temp = self.__convert_string_to_num( - dom_temperature_data['data']['Temperature']['value']) - if temp is not None: - transceiver_dom_info_dict['temperature'] = temp - - if self.dom_volt_supported: - start = QSFP_VOLT_OFFSET - QSFP_DOM_BULK_DATA_START - end = start + QSFP_VOLT_WIDTH - dom_voltage_data = sfpd_obj.parse_voltage( - dom_data_raw[start: end], 0) - volt = self.__convert_string_to_num( - dom_voltage_data['data']['Vcc']['value']) - if volt is not None: - transceiver_dom_info_dict['voltage'] = volt - - start = QSFP_CHANNL_MON_OFFSET - QSFP_DOM_BULK_DATA_START - end = start + QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( - dom_data_raw[start: end], 0) - - if self.dom_tx_power_supported: - transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['TX1Power']['value']) - transceiver_dom_info_dict['tx2power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['TX2Power']['value']) - transceiver_dom_info_dict['tx3power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['TX3Power']['value']) - transceiver_dom_info_dict['tx4power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['TX4Power']['value']) - - if self.dom_rx_power_supported: - transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['RX1Power']['value']) - transceiver_dom_info_dict['rx2power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['RX2Power']['value']) - transceiver_dom_info_dict['rx3power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['RX3Power']['value']) - transceiver_dom_info_dict['rx4power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['RX4Power']['value']) - - transceiver_dom_info_dict['tx1bias'] = dom_channel_monitor_data['data']['TX1Bias']['value'] - transceiver_dom_info_dict['tx2bias'] = dom_channel_monitor_data['data']['TX2Bias']['value'] - transceiver_dom_info_dict['tx3bias'] = dom_channel_monitor_data['data']['TX3Bias']['value'] - transceiver_dom_info_dict['tx4bias'] = dom_channel_monitor_data['data']['TX4Bias']['value'] - - else: - if not self.dom_supported: - return transceiver_dom_info_dict - - offset = 256 - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return transceiver_dom_info_dict - sfpd_obj._calibration_type = self.calibration - - dom_data_raw = self.__read_eeprom_specific_bytes( - (offset + SFP_DOM_BULK_DATA_START), SFP_DOM_BULK_DATA_SIZE) - - start = SFP_TEMPE_OFFSET - SFP_DOM_BULK_DATA_START - end = start + SFP_TEMPE_WIDTH - dom_temperature_data = sfpd_obj.parse_temperature( - dom_data_raw[start: end], 0) - - start = SFP_VOLT_OFFSET - SFP_DOM_BULK_DATA_START - end = start + SFP_VOLT_WIDTH - dom_voltage_data = sfpd_obj.parse_voltage( - dom_data_raw[start: end], 0) - - start = SFP_CHANNL_MON_OFFSET - SFP_DOM_BULK_DATA_START - end = start + SFP_CHANNL_MON_WIDTH - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( - dom_data_raw[start: end], 0) - - transceiver_dom_info_dict['temperature'] = self.__convert_string_to_num( - dom_temperature_data['data']['Temperature']['value']) - transceiver_dom_info_dict['voltage'] = self.__convert_string_to_num( - dom_voltage_data['data']['Vcc']['value']) - transceiver_dom_info_dict['rx1power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['RXPower']['value']) - transceiver_dom_info_dict['tx1bias'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['TXBias']['value']) - transceiver_dom_info_dict['tx1power'] = self.__convert_string_to_num( - dom_channel_monitor_data['data']['TXPower']['value']) - - transceiver_dom_info_dict['rx_los'] = self.get_rx_los() - transceiver_dom_info_dict['tx_fault'] = self.get_tx_fault() - transceiver_dom_info_dict['reset_status'] = self.get_reset_status() - transceiver_dom_info_dict['lp_mode'] = self.get_lpmode() - - return transceiver_dom_info_dict - - def get_transceiver_threshold_info(self): - """ - Retrieves transceiver threshold info of this SFP - Returns: - A dict which contains following keys/values : - ======================================================================== - keys |Value Format |Information - ---------------------------|---------------|---------------------------- - temphighalarm |FLOAT |High Alarm Threshold value of temperature in Celsius. - templowalarm |FLOAT |Low Alarm Threshold value of temperature in Celsius. - temphighwarning |FLOAT |High Warning Threshold value of temperature in Celsius. - templowwarning |FLOAT |Low Warning Threshold value of temperature in Celsius. - vcchighalarm |FLOAT |High Alarm Threshold value of supply voltage in mV. - vcclowalarm |FLOAT |Low Alarm Threshold value of supply voltage in mV. - vcchighwarning |FLOAT |High Warning Threshold value of supply voltage in mV. - vcclowwarning |FLOAT |Low Warning Threshold value of supply voltage in mV. - rxpowerhighalarm |FLOAT |High Alarm Threshold value of received power in dBm. - rxpowerlowalarm |FLOAT |Low Alarm Threshold value of received power in dBm. - rxpowerhighwarning |FLOAT |High Warning Threshold value of received power in dBm. - rxpowerlowwarning |FLOAT |Low Warning Threshold value of received power in dBm. - txpowerhighalarm |FLOAT |High Alarm Threshold value of transmit power in dBm. - txpowerlowalarm |FLOAT |Low Alarm Threshold value of transmit power in dBm. - txpowerhighwarning |FLOAT |High Warning Threshold value of transmit power in dBm. - txpowerlowwarning |FLOAT |Low Warning Threshold value of transmit power in dBm. - txbiashighalarm |FLOAT |High Alarm Threshold value of tx Bias Current in mA. - txbiaslowalarm |FLOAT |Low Alarm Threshold value of tx Bias Current in mA. - txbiashighwarning |FLOAT |High Warning Threshold value of tx Bias Current in mA. - txbiaslowwarning |FLOAT |Low Warning Threshold value of tx Bias Current in mA. - ======================================================================== - """ - transceiver_dom_threshold_info_dict = dict.fromkeys( - self.threshold_dict_keys, 'N/A') - - if self.sfp_type == OSFP_TYPE: - pass - - elif self.sfp_type == QSFP_TYPE: - if not self.dom_supported or not self.qsfp_page3_available: - return transceiver_dom_threshold_info_dict - - # Dom Threshold data starts from offset 384 - # Revert offset back to 0 once data is retrieved - offset = QSFP_MODULE_UPPER_PAGE3_START - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return transceiver_dom_threshold_info_dict - - dom_module_threshold_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_MODULE_THRESHOLD_OFFSET), QSFP_MODULE_THRESHOLD_WIDTH) - if dom_module_threshold_raw is None: - return transceiver_dom_threshold_info_dict - - dom_module_threshold_data = sfpd_obj.parse_module_threshold_values( - dom_module_threshold_raw, 0) - - dom_channel_threshold_raw = self.__read_eeprom_specific_bytes((offset + QSFP_CHANNL_THRESHOLD_OFFSET), - QSFP_CHANNL_THRESHOLD_WIDTH) - if dom_channel_threshold_raw is None: - return transceiver_dom_threshold_info_dict - dom_channel_threshold_data = sfpd_obj.parse_channel_threshold_values( - dom_channel_threshold_raw, 0) - - # Threshold Data - transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] - transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] - transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] - transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] - transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VccHighAlarm']['value'] - transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data['data']['VccHighWarning']['value'] - transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VccLowAlarm']['value'] - transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VccLowWarning']['value'] - transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_channel_threshold_data['data']['RxPowerHighAlarm']['value'] - transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_channel_threshold_data['data']['RxPowerHighWarning']['value'] - transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_channel_threshold_data['data']['RxPowerLowAlarm']['value'] - transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_channel_threshold_data['data']['RxPowerLowWarning']['value'] - transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_channel_threshold_data['data']['TxBiasHighAlarm']['value'] - transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_channel_threshold_data['data']['TxBiasHighWarning']['value'] - transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_channel_threshold_data['data']['TxBiasLowAlarm']['value'] - transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_channel_threshold_data['data']['TxBiasLowWarning']['value'] - transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_channel_threshold_data['data']['TxPowerHighAlarm']['value'] - transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_channel_threshold_data['data']['TxPowerHighWarning']['value'] - transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_channel_threshold_data['data']['TxPowerLowAlarm']['value'] - transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_channel_threshold_data['data']['TxPowerLowWarning']['value'] - - else: - offset = SFP_MODULE_ADDRA2_OFFSET - - if not self.dom_supported: - return transceiver_dom_threshold_info_dict - - sfpd_obj = sff8472Dom(None, self.calibration) - if sfpd_obj is None: - return transceiver_dom_threshold_info_dict - - dom_module_threshold_raw = self.__read_eeprom_specific_bytes((offset + SFP_MODULE_THRESHOLD_OFFSET), - SFP_MODULE_THRESHOLD_WIDTH) - if dom_module_threshold_raw is not None: - dom_module_threshold_data = sfpd_obj.parse_alarm_warning_threshold( - dom_module_threshold_raw, 0) - else: - return transceiver_dom_threshold_info_dict - - # Threshold Data - transceiver_dom_threshold_info_dict['temphighalarm'] = dom_module_threshold_data['data']['TempHighAlarm']['value'] - transceiver_dom_threshold_info_dict['templowalarm'] = dom_module_threshold_data['data']['TempLowAlarm']['value'] - transceiver_dom_threshold_info_dict['temphighwarning'] = dom_module_threshold_data['data']['TempHighWarning']['value'] - transceiver_dom_threshold_info_dict['templowwarning'] = dom_module_threshold_data['data']['TempLowWarning']['value'] - transceiver_dom_threshold_info_dict['vcchighalarm'] = dom_module_threshold_data['data']['VoltageHighAlarm']['value'] - transceiver_dom_threshold_info_dict['vcclowalarm'] = dom_module_threshold_data['data']['VoltageLowAlarm']['value'] - transceiver_dom_threshold_info_dict['vcchighwarning'] = dom_module_threshold_data[ - 'data']['VoltageHighWarning']['value'] - transceiver_dom_threshold_info_dict['vcclowwarning'] = dom_module_threshold_data['data']['VoltageLowWarning']['value'] - transceiver_dom_threshold_info_dict['txbiashighalarm'] = dom_module_threshold_data['data']['BiasHighAlarm']['value'] - transceiver_dom_threshold_info_dict['txbiaslowalarm'] = dom_module_threshold_data['data']['BiasLowAlarm']['value'] - transceiver_dom_threshold_info_dict['txbiashighwarning'] = dom_module_threshold_data['data']['BiasHighWarning']['value'] - transceiver_dom_threshold_info_dict['txbiaslowwarning'] = dom_module_threshold_data['data']['BiasLowWarning']['value'] - transceiver_dom_threshold_info_dict['txpowerhighalarm'] = dom_module_threshold_data['data']['TXPowerHighAlarm']['value'] - transceiver_dom_threshold_info_dict['txpowerlowalarm'] = dom_module_threshold_data['data']['TXPowerLowAlarm']['value'] - transceiver_dom_threshold_info_dict['txpowerhighwarning'] = dom_module_threshold_data['data']['TXPowerHighWarning']['value'] - transceiver_dom_threshold_info_dict['txpowerlowwarning'] = dom_module_threshold_data['data']['TXPowerLowWarning']['value'] - transceiver_dom_threshold_info_dict['rxpowerhighalarm'] = dom_module_threshold_data['data']['RXPowerHighAlarm']['value'] - transceiver_dom_threshold_info_dict['rxpowerlowalarm'] = dom_module_threshold_data['data']['RXPowerLowAlarm']['value'] - transceiver_dom_threshold_info_dict['rxpowerhighwarning'] = dom_module_threshold_data['data']['RXPowerHighWarning']['value'] - transceiver_dom_threshold_info_dict['rxpowerlowwarning'] = dom_module_threshold_data['data']['RXPowerLowWarning']['value'] - - return transceiver_dom_threshold_info_dict - - def get_reset_status(self): - """ - Retrieves the reset status of SFP - Returns: - A Boolean, True if reset enabled, False if disabled - """ - if not self.dom_supported: - return False - - if self.sfp_type == OSFP_TYPE: - return False - elif self.sfp_type == QSFP_TYPE: - offset = 0 - sfpd_obj = sff8436Dom() - dom_module_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_MODULE_MONITOR_OFFSET), QSFP_MODULE_MONITOR_WIDTH) - - if dom_module_monitor_raw is not None: - return True - else: - return False - elif self.sfp_type == SFP_TYPE: - offset = 0 - sfpd_obj = sff8472Dom() - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) - - if dom_channel_monitor_raw is not None: - return True - else: - return False - - def get_rx_los(self): - """ - Retrieves the RX LOS (lost-of-signal) status of SFP - Returns: - A Boolean, True if SFP has RX LOS, False if not. - Note : RX LOS status is latched until a call to get_rx_los or a reset. - """ - if not self.dom_supported: - return None - - rx_los_list = [] - if self.sfp_type == OSFP_TYPE: - return None - elif self.sfp_type == QSFP_TYPE: - offset = 0 - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_RX_LOS_STATUS_OFFSET), QSFP_CHANNL_RX_LOS_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - rx_los_data = int(dom_channel_monitor_raw[0], 16) - rx_los_list.append(rx_los_data & 0x01 != 0) - rx_los_list.append(rx_los_data & 0x02 != 0) - rx_los_list.append(rx_los_data & 0x04 != 0) - rx_los_list.append(rx_los_data & 0x08 != 0) - else: - offset = 256 - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - rx_los_data = int(dom_channel_monitor_raw[0], 16) - rx_los_list.append(rx_los_data & 0x02 != 0) - else: - return None - return rx_los_list - - def get_tx_fault(self): - """ - Retrieves the TX fault status of SFP - Returns: - A Boolean, True if SFP has TX fault, False if not - Note : TX fault status is lached until a call to get_tx_fault or a reset. - """ - if not self.dom_supported: - return None - - tx_fault_list = [] - if self.sfp_type == OSFP_TYPE: - return None - elif self.sfp_type == QSFP_TYPE: - offset = 0 - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_TX_FAULT_STATUS_OFFSET), QSFP_CHANNL_TX_FAULT_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - tx_fault_data = int(dom_channel_monitor_raw[0], 16) - tx_fault_list.append(tx_fault_data & 0x01 != 0) - tx_fault_list.append(tx_fault_data & 0x02 != 0) - tx_fault_list.append(tx_fault_data & 0x04 != 0) - tx_fault_list.append(tx_fault_data & 0x08 != 0) - else: - offset = 256 - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - tx_fault_data = int(dom_channel_monitor_raw[0], 16) - tx_fault_list.append(tx_fault_data & 0x04 != 0) - else: - return None - return tx_fault_list - - def get_tx_disable(self): - """ - Retrieves the tx_disable status of this SFP - Returns: - A Boolean, True if tx_disable is enabled, False if disabled - """ - if not self.dom_supported: - return None - - tx_disable_list = [] - if self.sfp_type == OSFP_TYPE: - return None - elif self.sfp_type == QSFP_TYPE: - offset = 0 - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_DISABLE_STATUS_OFFSET), QSFP_CHANNL_DISABLE_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - tx_disable_data = int(dom_channel_monitor_raw[0], 16) - tx_disable_list.append(tx_disable_data & 0x01 != 0) - tx_disable_list.append(tx_disable_data & 0x02 != 0) - tx_disable_list.append(tx_disable_data & 0x04 != 0) - tx_disable_list.append(tx_disable_data & 0x08 != 0) - else: - offset = 256 - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + SFP_CHANNL_STATUS_OFFSET), SFP_CHANNL_STATUS_WIDTH) - if dom_channel_monitor_raw is not None: - tx_disable_data = int(dom_channel_monitor_raw[0], 16) - tx_disable_list.append(tx_disable_data & 0xC0 != 0) - else: - return None - return tx_disable_list - - def get_tx_disable_channel(self): - """ - Retrieves the TX disabled channels in this SFP - Returns: - A hex of 4 bits (bit 0 to bit 3 as channel 0 to channel 3) to represent - TX channels which have been disabled in this SFP. - As an example, a returned value of 0x5 indicates that channel 0 - and channel 2 have been disabled. - """ - tx_disable_list = self.get_tx_disable() - if tx_disable_list is None: - return 0 - tx_disabled = 0 - for i in range(len(tx_disable_list)): - if tx_disable_list[i]: - tx_disabled |= 1 << i - return tx_disabled - - def get_lpmode(self): - """ - Retrieves the lpmode (low power mode) status of this SFP - Returns: - A Boolean, True if lpmode is enabled, False if disabled - """ - if self.sfp_type != OSFP_TYPE: - return False - - try: - reg_file = open( - "/".join([PORT_INFO_PATH, self.port_name, "qsfp_lpmode"])) - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - - # Read status - content = reg_file.readline().rstrip() - reg_value = int(content) - # low power mode is active high - if reg_value == 0: - return False - - return True - - def get_power_override(self): - """ - Retrieves the power-override status of this SFP - Returns: - A Boolean, True if power-override is enabled, False if disabled - """ - if self.sfp_type == QSFP_TYPE: - offset = 0 - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return False - - dom_control_raw = self.__read_eeprom_specific_bytes( - QSFP_CONTROL_OFFSET, QSFP_CONTROL_WIDTH) if self.get_presence() else None - if dom_control_raw is not None: - dom_control_data = sfpd_obj.parse_control_bytes( - dom_control_raw, 0) - power_override = ( - 'On' == dom_control_data['data']['PowerOverride']['value']) - else: - return False - - def get_temperature(self): - """ - Retrieves the temperature of this SFP - Returns: - An integer number of current temperature in Celsius - """ - transceiver_bulk_status = self.get_transceiver_bulk_status() - return transceiver_bulk_status.get("temperature", "N/A") - - def get_voltage(self): - """ - Retrieves the supply voltage of this SFP - Returns: - An integer number of supply voltage in mV - """ - transceiver_bulk_status = self.get_transceiver_bulk_status() - return transceiver_bulk_status.get("voltage", "N/A") - - def get_tx_bias(self): - """ - Retrieves the TX bias current of this SFP - Returns: - A list of four integer numbers, representing TX bias in mA - for channel 0 to channel 4. - Ex. ['110.09', '111.12', '108.21', '112.09'] - """ - transceiver_bulk_status = self.get_transceiver_bulk_status() - tx1_bs = transceiver_bulk_status.get("tx1bias", "N/A") - tx2_bs = transceiver_bulk_status.get("tx2bias", "N/A") - tx3_bs = transceiver_bulk_status.get("tx3bias", "N/A") - tx4_bs = transceiver_bulk_status.get("tx4bias", "N/A") - tx_bias_list = [tx1_bs, tx2_bs, tx3_bs, tx4_bs] - return tx_bias_list - - def get_rx_power(self): - """ - Retrieves the received optical power for this SFP - Returns: - A list of four integer numbers, representing received optical - power in mW for channel 0 to channel 4. - Ex. ['1.77', '1.71', '1.68', '1.70'] - """ - rx_power_list = [] - if self.sfp_type == OSFP_TYPE: - # OSFP not supported on our platform yet. - return None - - elif self.sfp_type == QSFP_TYPE: - offset = 0 - offset_xcvr = 128 - - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return None - - if self.dom_rx_power_supported: - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( - dom_channel_monitor_raw, 0) - rx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['RX1Power']['value'])) - rx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['RX2Power']['value'])) - rx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['RX3Power']['value'])) - rx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['RX4Power']['value'])) - else: - return None - else: - return None - else: - offset = 256 - - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return None - - if self.dom_supported: - sfpd_obj._calibration_type = self.calibration - - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( - dom_channel_monitor_raw, 0) - rx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['RXPower']['value'])) - else: - return None - else: - return None - - return rx_power_list - - def get_tx_power(self): - """ - Retrieves the TX power of this SFP - Returns: - A list of four integer numbers, representing TX power in mW - for channel 0 to channel 4. - Ex. ['1.86', '1.86', '1.86', '1.86'] - """ - tx_power_list = [] - if self.sfp_type == OSFP_TYPE: - # OSFP not supported on our platform yet. - return None - - elif self.sfp_type == QSFP_TYPE: - offset = 0 - offset_xcvr = 128 - - sfpd_obj = sff8436Dom() - if sfpd_obj is None: - return None - - if self.dom_tx_power_supported: - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + QSFP_CHANNL_MON_OFFSET), QSFP_CHANNL_MON_WITH_TX_POWER_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params_with_tx_power( - dom_channel_monitor_raw, 0) - tx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['TX1Power']['value'])) - tx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['TX2Power']['value'])) - tx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['TX3Power']['value'])) - tx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['TX4Power']['value'])) - else: - return None - else: - return None - else: - offset = 256 - sfpd_obj = sff8472Dom() - if sfpd_obj is None: - return None - - if self.dom_supported: - sfpd_obj._calibration_type = self.calibration - - dom_channel_monitor_raw = self.__read_eeprom_specific_bytes( - (offset + SFP_CHANNL_MON_OFFSET), SFP_CHANNL_MON_WIDTH) - if dom_channel_monitor_raw is not None: - dom_channel_monitor_data = sfpd_obj.parse_channel_monitor_params( - dom_channel_monitor_raw, 0) - tx_power_list.append(self.__convert_string_to_num( - dom_channel_monitor_data['data']['TXPower']['value'])) - else: - return None - else: - return None - return tx_power_list - - def reset(self): - """ - Reset SFP and return all user module settings to their default srate. - Returns: - A boolean, True if successful, False if not - """ - if self.sfp_type != OSFP_TYPE: - return False - - try: - reg_file = open( - "/".join([PORT_INFO_PATH, self.port_name, "qsfp_resetL"]), "w") - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - - # Convert our register value back to a hex string and write back - reg_file.seek(0) - reg_file.write(hex(0)) - reg_file.close() - - # Sleep 1 second to allow it to settle - time.sleep(1) - - # Flip the bit back high and write back to the register to take port out of reset - try: - reg_file = open( - "/".join([PORT_INFO_PATH, self.port_name, "qsfp_resetL"]), "w") - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - - reg_file.seek(0) - reg_file.write(hex(1)) - reg_file.close() - - return True - - def tx_disable(self, tx_disable): - """ - Disable SFP TX for all channels - Args: - tx_disable : A Boolean, True to enable tx_disable mode, False to disable - tx_disable mode. - Returns: - A boolean, True if tx_disable is set successfully, False if not - """ - if self.sfp_type == QSFP_TYPE: - sysfsfile_eeprom = None - try: - tx_disable_ctl = 0xf if tx_disable else 0x0 - buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True - return False - - def tx_disable_channel(self, channel, disable): - """ - Sets the tx_disable for specified SFP channels - Args: - channel : A hex of 4 bits (bit 0 to bit 3) which represent channel 0 to 3, - e.g. 0x5 for channel 0 and channel 2. - disable : A boolean, True to disable TX channels specified in channel, - False to enable - Returns: - A boolean, True if successful, False if not - """ - if self.sfp_type == QSFP_TYPE: - sysfsfile_eeprom = None - try: - channel_state = self.get_tx_disable_channel() - tx_enable_mask = [0xe, 0xd, 0xb, 0x7] - tx_disable_mask = [0x1, 0x3, 0x7, 0xf] - tx_disable_ctl = channel_state | tx_disable_mask[ - channel] if disable else channel_state & tx_enable_mask[channel] - buffer = create_string_buffer(1) - buffer[0] = chr(tx_disable_ctl) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_CONTROL_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True - return False - - def set_lpmode(self, lpmode): - """ - Sets the lpmode (low power mode) of SFP - Args: - lpmode: A Boolean, True to enable lpmode, False to disable it - Note : lpmode can be overridden by set_power_override - Returns: - A boolean, True if lpmode is set successfully, False if not - """ - if self.sfp_type != OSFP_TYPE: - return False - - try: - reg_file = open( - "/".join([PORT_INFO_PATH, self.port_name, "qsfp_lpmode"]), "r+") - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - - content = hex(lpmode) - - reg_file.seek(0) - reg_file.write(content) - reg_file.close() - - return True - - def set_power_override(self, power_override, power_set): - """ - Sets SFP power level using power_override and power_set - Args: - power_override : - A Boolean, True to override set_lpmode and use power_set - to control SFP power, False to disable SFP power control - through power_override/power_set and use set_lpmode - to control SFP power. - power_set : - Only valid when power_override is True. - A Boolean, True to set SFP to low power mode, False to set - SFP to high power mode. - Returns: - A boolean, True if power-override and power_set are set successfully, - False if not - """ - if self.sfp_type == QSFP_TYPE: - try: - power_override_bit = 0 - if power_override: - power_override_bit |= 1 << 0 - - power_set_bit = 0 - if power_set: - power_set_bit |= 1 << 1 - - buffer = create_string_buffer(1) - buffer[0] = chr(power_override_bit | power_set_bit) - # Write to eeprom - sysfsfile_eeprom = open( - self.port_to_eeprom_mapping[self.port_num], "r+b") - sysfsfile_eeprom.seek(QSFP_POWEROVERRIDE_OFFSET) - sysfsfile_eeprom.write(buffer[0]) - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - finally: - if sysfsfile_eeprom is not None: - sysfsfile_eeprom.close() - time.sleep(0.01) - return True - return False - - def get_name(self): - """ - Retrieves the name of the device - Returns: - string: The name of the device - """ - sfputil_helper = SfpUtilHelper() - sfputil_helper.read_porttab_mappings( - self.__get_path_to_port_config_file()) - name = sfputil_helper.logical[self.index] or "Unknown" - return name - - def get_presence(self): - """ - Retrieves the presence of the PSU - Returns: - bool: True if PSU is present, False if not - """ - sysfs_filename = "sfp_modabs" if self.sfp_type == SFP_TYPE else "qsfp_modprsL" - reg_path = "/".join([PORT_INFO_PATH, self.port_name, sysfs_filename]) - - # Read status - try: - reg_file = open(reg_path) - content = reg_file.readline().rstrip() - reg_value = int(content) - except IOError as e: - print("Error: unable to open file: %s" % str(e)) - return False - - # Module present is active low - if reg_value == 0: - return True - - return False - - def get_model(self): - """ - Retrieves the model number (or part number) of the device - Returns: - string: Model/part number of device - """ - transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("model", "N/A") - - def get_serial(self): - """ - Retrieves the serial number of the device - Returns: - string: Serial number of device - """ - transceiver_dom_info_dict = self.get_transceiver_info() - return transceiver_dom_info_dict.get("serial", "N/A") - - def get_status(self): - """ - Retrieves the operational status of the device - Returns: - A boolean value, True if device is operating properly, False if not - """ - return self.get_presence() diff --git a/device/celestica/x86_64-cel_silverstone-r0/system_health_monitoring_config.json b/device/celestica/x86_64-cel_silverstone-r0/system_health_monitoring_config.json new file mode 100644 index 0000000000..56fda7de4f --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/system_health_monitoring_config.json @@ -0,0 +1,13 @@ +{ + "services_to_ignore": [], + "devices_to_ignore": [ + "psu.temperature" + ], + "user_defined_checkers": [], + "polling_interval": 60, + "led_color": { + "fault": "amber", + "normal": "green", + "booting": "green_blink_1hz" + } +} diff --git a/device/celestica/x86_64-cel_silverstone-r0/warm-reboot_plugin b/device/celestica/x86_64-cel_silverstone-r0/warm-reboot_plugin new file mode 100755 index 0000000000..22212b5afe --- /dev/null +++ b/device/celestica/x86_64-cel_silverstone-r0/warm-reboot_plugin @@ -0,0 +1,4 @@ +#!/bin/bash + +# Set all LEDs to BMC's control +ipmitool raw 0x3a 0x09 0x02 0x01 &> /dev/null diff --git a/platform/broadcom/one-image.mk b/platform/broadcom/one-image.mk index c9660299ed..075833db9d 100755 --- a/platform/broadcom/one-image.mk +++ b/platform/broadcom/one-image.mk @@ -54,7 +54,8 @@ $(SONIC_ONE_IMAGE)_LAZY_INSTALLS += $(DELL_S6000_PLATFORM_MODULE) \ $(CEL_DX010_PLATFORM_MODULE) \ $(CEL_HALIBURTON_PLATFORM_MODULE) \ $(CEL_SEASTONE2_PLATFORM_MODULE) \ - $(CEL_BELGITE_PLATFORM_MODULE) \ + $(CEL_DS1000_PLATFORM_MODULE) \ + $(CEL_QUESTONE2_PLATFORM_MODULE) \ $(DELTA_AG9032V1_PLATFORM_MODULE) \ $(DELTA_AG9064_PLATFORM_MODULE) \ $(DELTA_AG5648_PLATFORM_MODULE) \ diff --git a/platform/broadcom/platform-modules-cel.mk b/platform/broadcom/platform-modules-cel.mk index b25aeb7c09..354d5ce963 100644 --- a/platform/broadcom/platform-modules-cel.mk +++ b/platform/broadcom/platform-modules-cel.mk @@ -1,16 +1,18 @@ # Celestica DX010 and Haliburton Platform modules -CEL_DX010_PLATFORM_MODULE_VERSION = 0.9 -CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 0.9 -CEL_SEASTONE2_PLATFORM_MODULE_VERSION = 0.9 -CEL_SILVERSTONE_PLATFORM_MODULE_VERSION = 0.9 -CEL_BELGITE_PLATFORM_MODULE_VERSION = 0.9 +CEL_DX010_PLATFORM_MODULE_VERSION = 1.0 +CEL_HALIBURTON_PLATFORM_MODULE_VERSION = 1.0 +CEL_SEASTONE2_PLATFORM_MODULE_VERSION = 1.0 +CEL_SILVERSTONE_PLATFORM_MODULE_VERSION = 1.0 +CEL_DS1000_PLATFORM_MODULE_VERSION = 1.0 +CEL_QUESTONE2_PLATFORM_MODULE_VERSION = 1.0 export CEL_DX010_PLATFORM_MODULE_VERSION export CEL_HALIBURTON_PLATFORM_MODULE_VERSION export CEL_SEASTONE2_PLATFORM_MODULE_VERSION export CEL_SILVERSTONE_PLATFORM_MODULE_VERSION -export CEL_BELGITE_PLATFORM_MODULE_VERSION +export CEL_DS1000_PLATFORM_MODULE_VERSION +export CEL_QUESTONE2_PLATFORM_MODULE_VERSION CEL_DX010_PLATFORM_MODULE = platform-modules-dx010_$(CEL_DX010_PLATFORM_MODULE_VERSION)_amd64.deb $(CEL_DX010_PLATFORM_MODULE)_SRC_PATH = $(PLATFORM_PATH)/sonic-platform-modules-cel @@ -30,6 +32,10 @@ CEL_SILVERSTONE_PLATFORM_MODULE = platform-modules-silverstone_$(CEL_SILVERSTONE $(CEL_SILVERSTONE_PLATFORM_MODULE)_PLATFORM = x86_64-cel_silverstone-r0 $(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_SILVERSTONE_PLATFORM_MODULE))) -CEL_BELGITE_PLATFORM_MODULE = platform-modules-belgite_$(CEL_BELGITE_PLATFORM_MODULE_VERSION)_amd64.deb -$(CEL_BELGITE_PLATFORM_MODULE)_PLATFORM = x86_64-cel_belgite-r0 -$(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_BELGITE_PLATFORM_MODULE))) +CEL_DS1000_PLATFORM_MODULE = platform-modules-ds1000_$(CEL_DS1000_PLATFORM_MODULE_VERSION)_amd64.deb +$(CEL_DS1000_PLATFORM_MODULE)_PLATFORM = x86_64-cel_ds1000-r0 +$(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_DS1000_PLATFORM_MODULE))) + +CEL_QUESTONE2_PLATFORM_MODULE = platform-modules-questone2_$(CEL_QUESTONE2_PLATFORM_MODULE_VERSION)_amd64.deb +$(CEL_QUESTONE2_PLATFORM_MODULE)_PLATFORM = x86_64-cel_questone_2-r0 +$(eval $(call add_extra_package,$(CEL_DX010_PLATFORM_MODULE),$(CEL_QUESTONE2_PLATFORM_MODULE))) diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/__init__.py deleted file mode 100644 index 0533d11584..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# All the derived classes for PDDF -__all__ = ["platform", "chassis", "sfp", "psu", "thermal"] -from sonic_platform import * #[py/polluting-import] - diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/fan.py deleted file mode 100644 index 5ece7e9809..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/fan.py +++ /dev/null @@ -1,93 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_fan import PddfFan - import subprocess -except ImportError as e: - raise ImportError(str(e) + "- required module not found") -# ------------------------------------------------------------------ -# HISTORY: -# 5/1/2022 (A.D.) -# add function:set_status_led, -# Solve the problem that when a fan is pulled out, the Fan LED on the front panel is still green Issue-#11525 -# ------------------------------------------------------------------ - - -class Fan(PddfFan): - """PDDF Platform-Specific Fan class""" - - def __init__(self, tray_idx, fan_idx=0, pddf_data=None, pddf_plugin_data=None, is_psu_fan=False, psu_index=0): - # idx is 0-based - PddfFan.__init__(self, tray_idx, fan_idx, pddf_data, pddf_plugin_data, is_psu_fan, psu_index) - - - 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 - """ - # Fix the speed vairance to 10 percent. If it changes based on platforms, overwrite - # this value in derived pddf fan class - return 20 - - def get_presence(self): - if self.is_psu_fan: - #For PSU, FAN must be present when PSU is present - try: - cmd = ['i2cget', '-y', '-f', '0x2', '0x32', '0x41'] - p = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True) - data = p.communicate() - status = int(data[0].strip(), 16) - if (self.fans_psu_index == 1 and (status & 0x10) == 0) or \ - (self.fans_psu_index == 2 and (status & 0x20) == 0): - return True - except (IOError, ValueError): - pass - - return False - else: - #Overwirte the PDDF Common since the FANs on Belgite are all Fixed and present - return True - - def get_direction(self): - """ - Retrieves the direction of fan - - Returns: - A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST - depending on fan direction - """ - if self.is_psu_fan: - # Belgite PSU module only has EXHAUST fan - return "EXHAUST" - else: - return super().get_direction() - - def get_status_led(self): - """ - Gets the state of the fan status LED - - Returns: - A string, one of the predefined STATUS_LED_COLOR_* strings above - """ - if self.is_psu_fan: - return "N/A" - else: - return super().get_status_led() - - def set_status_led(self, color): - """ - Sets the state of the fan module status LED - - Args: - color: A string representing the color with which to set the - fan module status LED - - Returns: - bool: True if status LED state is set successfully, False if not - """ - if self.is_psu_fan: - return False - else: - return super().set_status_led(color) diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/sfp.py deleted file mode 100644 index a216a37afc..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/sfp.py +++ /dev/null @@ -1,15 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_sfp import PddfSfp -except ImportError as e: - raise ImportError (str(e) + "- required module not found") - - -class Sfp(PddfSfp): - """ - PDDF Platform-Specific Sfp class - """ - - def __init__(self, index, pddf_data=None, pddf_plugin_data=None): - PddfSfp.__init__(self, index, pddf_data, pddf_plugin_data) - - # Provide the functions/variables below for which implementation is to be overwritten diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/thermal.py deleted file mode 100644 index 7dd294fb84..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/thermal.py +++ /dev/null @@ -1,111 +0,0 @@ -try: - from sonic_platform_pddf_base.pddf_thermal import PddfThermal -except ImportError as e: - raise ImportError(str(e) + "- required module not found") - - - -class Thermal(PddfThermal): - """PDDF Platform-Specific Thermal class""" - - def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): - PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) - self.minimum_thermal = self.get_temperature() - self.maximum_thermal = self.get_temperature() - # Provide the functions/variables below for which implementation is to be overwritten - - def get_low_critical_threshold(self): - """ - Retrieves the low critical threshold temperature of thermal - Returns: - A float number, the low critical threshold temperature of thermal in Celsius - up to nearest thousandth of one degree Celsius, e.g. 30.125 - """ - return 0.001 - - def get_high_critical_threshold(self): - """ - Retrieves the high critical threshold temperature of thermal - Returns: - A float number, the high critical threshold temperature of thermal in Celsius - up to nearest thousandth of one degree Celsius, e.g. 30.125 - """ - - return 100.000 - - def get_minimum_recorded(self): - """ - Retrieves the minimum recorded temperature of thermal - Returns: - A float number, the minimum recorded temperature of thermal in Celsius - up to nearest thousandth of one degree Celsius, e.g. 30.125 - """ - tmp = self.get_temperature() - if tmp < self.minimum_thermal: - self.minimum_thermal = tmp - - return self.minimum_thermal - - def get_maximum_recorded(self): - """ - Retrieves the maximum recorded temperature of thermal - Returns: - A float number, the maximum recorded temperature of thermal in Celsius - up to nearest thousandth of one degree Celsius, e.g. 30.125 - """ - tmp = self.get_temperature() - if tmp > self.maximum_thermal: - self.maximum_thermal = tmp - - return self.maximum_thermal - - def get_presence(self): - """ - Retrieves the presence of the PSU - Returns: - bool: True if Thermal is present, False if not - """ - return True - - def get_model(self): - """ - Retrieves the model number (or part number) of the device - Returns: - string: Model/part number of device - """ - return "N/A" - - def get_serial(self): - """ - Retrieves the serial number of the device - Returns: - string: Serial number of device - """ - return "N/A" - - def get_status(self): - """ - Retrieves the operational status of the device - Returns: - A boolean value, True if device is operating properly, False if not - """ - if not self.get_presence(): - return False - - return True - - def is_replaceable(self): - """ - Retrieves whether thermal module is replaceable - Returns: - A boolean value, True if replaceable, False if not - """ - return False - - def get_position_in_parent(self): - """ - Retrieves the thermal position information - Returns: - A int value, 0 represent ASIC thermal, 1 represent CPU thermal info - """ - return 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/scripts/pddf_post_device_create.sh b/platform/broadcom/sonic-platform-modules-cel/belgite/scripts/pddf_post_device_create.sh deleted file mode 100755 index 436cf61d6d..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/scripts/pddf_post_device_create.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -# Set U60 shutdown threhold 80 -sudo i2cset -y -f 6 0x49 0x3 0x4e 0x00 i -sleep 0.1 -sudo i2cset -y -f 6 0x49 0x1 0x2 -sleep 0.1 -#Set LM75 shutdown enable -sudo i2cset -y -f 2 0x32 0x45 0x1 - -# set sys led green status -sudo i2cset -y -f 2 0x32 0x43 0xec - -echo -2 | tee /sys/bus/i2c/drivers/pca954x/*-00*/idle_state diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/service/belgite-pddf-platform-monitor.service b/platform/broadcom/sonic-platform-modules-cel/belgite/service/belgite-pddf-platform-monitor.service deleted file mode 100644 index 233971ae78..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/service/belgite-pddf-platform-monitor.service +++ /dev/null @@ -1,16 +0,0 @@ -[Unit] -Description=Belgite Platform Monitoring service -Before=pmon.service -After=pddf-platform-init.service -DefaultDependencies=no - -[Service] -ExecStart=/usr/local/bin/belgite_pddf_monitor.py -KillSignal=SIGKILL -SuccessExitStatus=SIGKILL - -# Resource Limitations -LimitCORE=infinity - -[Install] -WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/utils/belgite_pddf_monitor.py b/platform/broadcom/sonic-platform-modules-cel/belgite/utils/belgite_pddf_monitor.py deleted file mode 100755 index 5ce0469a0d..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/utils/belgite_pddf_monitor.py +++ /dev/null @@ -1,272 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (C) Celestica Technology 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 -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# ------------------------------------------------------------------ -# HISTORY: -# 9/16/2021 (A.D.) -# ------------------------------------------------------------------ - -try: - import sys - import getopt - import logging - import logging.config - import time # this is only being used as part of the example - import signal - import math - from sonic_platform import platform - from sonic_py_common.general import getstatusoutput_noshell -except ImportError as e: - raise ImportError('%s - required module not found' % str(e)) - -# Deafults -FUNCTION_NAME = 'cel_belgite_monitor' -DUTY_MAX = 100 -FAN_NUMBER = 3 -SENSOR_NUMBER = 4 -CPU_CORE_TEMP = r"/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp1_input" - - -class cel_belgite_monitor(object): - """ - Make a class we can use to capture stdout and sterr in the log - """ - # static temp var - _ori_temp = 0 - _new_perc = DUTY_MAX / 2 - syslog = logging.getLogger("[" + FUNCTION_NAME + "]") - init_fan_temperature = [0, 0, 0, 0] - - def __init__(self, log_file, log_level): - """Needs a logger and a logger level.""" - formatter = logging.Formatter('%(name)s %(message)s') - sys_handler = logging.handlers.SysLogHandler(address='/dev/log') - sys_handler.setFormatter(formatter) - sys_handler.ident = 'common' - self.syslog.setLevel(logging.WARNING) - self.syslog.addHandler(sys_handler) - self.platform_chassis_obj = platform.Platform().get_chassis() - # set up logging to file - logging.basicConfig( - filename=log_file, - filemode='w', - level=log_level, - format='[%(asctime)s] {%(pathname)s:%(lineno)d} %(levelname)s - %(message)s', - datefmt='%H:%M:%S' - ) - - # set up logging to console - if log_level == logging.DEBUG: - console = logging.StreamHandler() - console.setLevel(log_level) - formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s') - console.setFormatter(formatter) - logging.getLogger('').addHandler(console) - logging.debug('SET. logfile:%s / loglevel:%d' % (log_file, log_level)) - - def get_all_temperature(self): - """ - return: all temperature - """ - all_temperature_list = list() - for sensor_index in range(SENSOR_NUMBER): - temp = self.platform_chassis_obj.get_thermal(sensor_index).get_temperature() - if temp is None or str(temp).strip() == "": - return False - temp = temp*1000 - all_temperature_list.append(temp) - u4_temperature = all_temperature_list[0] - u7_temperature = all_temperature_list[1] - # default CPU temperature 70 - cpu_temperature = 70000 - try: - with open(CPU_CORE_TEMP, "r") as f: - cpu_temperature = float(f.read().strip()) - except Exception as E: - logging.debug('Error: %s' % E) - u60_temperature = all_temperature_list[3] - return [u4_temperature, u7_temperature, cpu_temperature, u60_temperature] - - def get_fan_speed_by_temperature(self, temp_list): - fan1_direction = self.platform_chassis_obj.get_fan(0).get_direction() - logging.debug('INFO: fan direction: %s' % str(fan1_direction)) - all_temp = self.get_all_temperature() - logging.debug('INFO: all_temp: %s' % str(all_temp)) - # B2F=intake: U7 temperature, F2B-EXHAUST: U4 temperature - a = 1 if fan1_direction.lower() == "intake" else 0 - sensor_temp = all_temp[a] - cup_temp = all_temp[2] - u60_temp = all_temp[3] - logging.debug('sensor_temp:%d cup_temp:%d u60_temp:%d' % (sensor_temp, cup_temp, u60_temp)) - update_temp_sensor, update_temp_cpu, update_temp_u60 = True, True, True - if all_temp[a] - temp_list[a] < 0: - update_temp_sensor = False - if cup_temp - temp_list[2] < 0: - update_temp_cpu = False - if u60_temp - temp_list[3] < 0: - update_temp_u60 = False - - # U4 U7 - if not update_temp_sensor: # temperature down - b = math.trunc(1400/13) - if sensor_temp <= 32000: - sensor_temp_speed = 40 - elif sensor_temp >= 45000: - sensor_temp_speed = 100 - else: - sensor_temp_speed = int(math.trunc(60 / 13) * math.trunc(sensor_temp / 1000) - b) - else: # temperature up - b = math.trunc(1580 / 13) - if sensor_temp <= 35000: - sensor_temp_speed = 40 - elif sensor_temp >= 48000: - sensor_temp_speed = 100 - else: - sensor_temp_speed = int(math.trunc(60/13) * math.trunc(sensor_temp/1000) - b) - - # CPU - if not update_temp_cpu: # temperature down - b = 228 - if cup_temp <= 67000: - cpu_temp_speed = 40 - elif cup_temp >= 82000: - cpu_temp_speed = 100 - else: - cpu_temp_speed = int(4 * (cup_temp / 1000) - b) - else: # temperature up - b = 240 - if cup_temp <= 70000: - cpu_temp_speed = 40 - elif cup_temp >= 85000: - cpu_temp_speed = 100 - else: - cpu_temp_speed = int(4 * (cup_temp / 1000) - b) - - # U60 - if not update_temp_u60: # temperature down - b = 168 - if u60_temp <= 52000: - u60_temp_speed = 40 - elif u60_temp >= 67000: - u60_temp_speed = 100 - else: - u60_temp_speed = int(4 * (u60_temp / 1000) - b) - else: # temperature up - b = 180 - if u60_temp <= 55000: - u60_temp_speed = 40 - elif u60_temp >= 70000: - u60_temp_speed = 100 - else: - u60_temp_speed = int(4 * (u60_temp / 1000) - b) - return max([sensor_temp_speed, cpu_temp_speed, u60_temp_speed]) - - def manage_fans(self): - fan_presence_list = [True, True, True] # whether fan is absent or not - for fan_index in range(FAN_NUMBER): - if not self.platform_chassis_obj.get_fan(fan_index).get_presence() or not \ - self.platform_chassis_obj.get_fan(fan_index).get_status(): - fan_presence_list[fan_index] = False - logging.debug('self.platform_chassis_obj.get_fan(fan_index).get_presence():%s' - % str(self.platform_chassis_obj.get_fan(fan_index).get_presence())) - logging.debug('self.platform_chassis_obj.get_fan(fan_index).get_status():%s' - % str(self.platform_chassis_obj.get_fan(fan_index).get_status())) - else: - fan_presence_list[fan_index] = True - - fans_inserted_num = FAN_NUMBER - fan_presence_list.count(False) - if fans_inserted_num == 0: # all fans broken, power off - self.syslog.critical("No fans inserted. Severe overheating hazard. " - "Please insert Fans immediately or power off the device\n") - - # power off - elif fans_inserted_num in [1, 2]: # 1 or 2 present, full speed - self._new_perc = DUTY_MAX - else: # 3 fans normal, manage the fans follow thermal policy - self._new_perc = self.get_fan_speed_by_temperature(self.init_fan_temperature) - logging.debug('INFO: 3 fans inserted: self._new_perc: %s' % str(self._new_perc)) - self.init_fan_temperature = self.get_all_temperature() - - for i in range(FAN_NUMBER): - aa = self.platform_chassis_obj.get_fan(i).get_speed() - logging.debug("INFO: Get before setting fan speed: %s" % aa) - if self._new_perc < 40: - self._new_perc = 40 - if self._new_perc > 100: - self._new_perc = 100 - set_stat = self.platform_chassis_obj.get_fan(i).set_speed(self._new_perc) - if set_stat is True: - logging.debug('INFO: PASS. set_fan%d_duty_cycle (%d)' % (i, self._new_perc)) - else: - logging.debug('INFO: FAIL. set_fan%d_duty_cycle (%d)' % (i, self._new_perc)) - - -def handler(signum, frame): - platform_chassis = platform.Platform().get_chassis() - for _ in range(FAN_NUMBER): - set_stat = platform_chassis.get_fan(_).set_speed(DUTY_MAX) - if set_stat is True: - logging.debug('INFO:Cause signal %d, set fan speed max.' % signum) - else: - logging.debug('INFO: FAIL. set_fan_duty_cycle (%d)' % DUTY_MAX) - # Enable the CPLD Heartbeat back - status, output = getstatusoutput_noshell(["i2cset", "-f", "-y", "75", "0x40", "0x22", "0x00"]) - if status == 0: - logging.debug('INFO: CPLD Heartbeat check is enabled back') - sys.exit(0) - - -def main(argv): - global test_temp - - log_file = '/home/admin/%s.log' % FUNCTION_NAME - log_level = logging.INFO - if len(sys.argv) != 1: - try: - opts, args = getopt.getopt(argv, 'hdlt:', ['lfile=']) - except getopt.GetoptError: - print('Usage: %s [-d] [-l ]' % sys.argv[0]) - return 0 - for opt, arg in opts: - if opt == '-h': - print('Usage: %s [-d] [-l ]' % sys.argv[0]) - return 0 - elif opt in ('-d', '--debug'): - log_level = logging.DEBUG - elif opt in ('-l', '--lfile'): - log_file = arg - - if sys.argv[1] == '-t': - if len(sys.argv) != 6: - print("temp test, need input 4 temp") - return 0 - - signal.signal(signal.SIGINT, handler) - signal.signal(signal.SIGTERM, handler) - # Disaable the CPLD Heartbeat check to control Fan speed from CPU via ADT7470 - getstatusoutput_noshell(['i2cset', '-f', '-y', '2', '0x32', '0x30', '0x01']) - - monitor = cel_belgite_monitor(log_file, log_level) - - # Loop forever, doing something useful hopefully: - while True: - monitor.manage_fans() - time.sleep(10) - - -if __name__ == '__main__': - main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/changelog b/platform/broadcom/sonic-platform-modules-cel/debian/changelog index aa89b4df63..a2ce38fdca 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/changelog +++ b/platform/broadcom/sonic-platform-modules-cel/debian/changelog @@ -1,3 +1,11 @@ +sonic-cel-platform-modules (1.0) unstable; urgency=low + + * Add questone2 platform module. + * Rename Belgite to DS1000 + * Hardened platform bug fixes + + -- Jemston Fernando Thu, 30 Nov 2023 15:00:00 +0530 + sonic-cel-platform-modules (0.9) unstable; urgency=low * Add haliburton platform module. diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index 0dd6eb76e0..cef0dfd391 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -26,7 +26,12 @@ Architecture: amd64 Depends: linux-image-6.1.0-11-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp. -Package: platform-modules-belgite +Package: platform-modules-ds1000 +Architecture: amd64 +Depends: linux-image-5.10.0-23-2-amd64-unsigned +Description: kernel modules for platform devices such as led, sfp + +Package: platform-modules-questone2 Architecture: amd64 Depends: linux-image-6.1.0-11-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-belgite.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-belgite.install deleted file mode 100644 index 6f9f8f267e..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-belgite.install +++ /dev/null @@ -1,7 +0,0 @@ -belgite/systemd/pddf-platform-init.service etc/systemd/system -belgite/service/belgite-pddf-platform-monitor.service lib/systemd/system -belgite/scripts/pddf_pre_driver_install.sh usr/local/bin -belgite/scripts/pddf_post_device_create.sh usr/local/bin -belgite/utils/belgite_pddf_monitor.py usr/local/bin -belgite/pddf/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-cel_belgite-r0/pddf -services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds1000.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds1000.install new file mode 100644 index 0000000000..24a75dfe82 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds1000.install @@ -0,0 +1,8 @@ +ds1000/systemd/pddf-platform-init.service etc/systemd/system +ds1000/service/ds1000-fan-control.service lib/systemd/system +ds1000/scripts/pddf_pre_driver_install.sh usr/local/bin +ds1000/scripts/pddf_post_device_create.sh usr/local/bin +ds1000/scripts/ds1000_platform_shutdown.sh usr/local/bin +ds1000/utils/ds1000_fanctld.py usr/local/bin +ds1000/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-cel_ds1000-r0/pddf +services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-belgite.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds1000.postinst similarity index 56% rename from platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-belgite.postinst rename to platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds1000.postinst index 4abd671bae..1b038ebcc3 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-belgite.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-ds1000.postinst @@ -1,6 +1,6 @@ depmod -a /usr/local/bin/platform_api_mgnt.sh install systemctl enable pddf-platform-init.service +systemctl enable ds1000-fan-control.service systemctl start pddf-platform-init.service -systemctl enable belgite-pddf-platform-monitor.service -systemctl start belgite-pddf-platform-monitor.service +systemctl start ds1000-fan-control.service 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 fab61467da..6e643e524d 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 @@ -40,8 +40,14 @@ fi case "$1" in start) echo -n "Setting up board... " - + modprobe i2c-i801 + modprobe i2c-isch + modprobe i2c-ismt modprobe i2c-dev + modprobe i2c-mux + modprobe i2c-smbus + modprobe i2c-mux-gpio + modprobe i2c-mux-pca954x force-deselect-on-exit=1 modprobe dx010_wdt modprobe leds-dx010 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init index aff8503d75..9a5bcdac47 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-haliburton.init @@ -35,6 +35,15 @@ case "$1" in start) echo -n "Setting up board... " + modprobe i2c-i801 + modprobe i2c-isch + modprobe i2c-ismt + modprobe i2c-dev + modprobe i2c-mux + modprobe i2c-smbus + modprobe i2c-mux-gpio + modprobe i2c-mux-pca954x + modprobe smc modprobe hlx_gpio_ich modprobe dps200 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.install new file mode 100644 index 0000000000..1b6114d360 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.install @@ -0,0 +1,10 @@ +questone2/cfg/questone2-modules.conf etc/modules-load.d +questone2/cfg/questone2-modprobe.conf etc/modprobe.d +questone2/systemd/platform-modules-questone2.service lib/systemd/system +questone2/cfg/pid_config_questone2.ini usr/local/etc +questone2/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-cel_questone_2-r0 +questone2/scripts/questone2_platform_shutdown.sh usr/local/bin +questone2/scripts/sensors usr/bin +questone2/scripts/platform_sensors.py usr/local/bin +services/platform_api/platform_api_mgnt.sh usr/local/bin +services/platform_api/ps_mem.py usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.postinst new file mode 100644 index 0000000000..7a7371851f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.postinst @@ -0,0 +1,6 @@ +depmod -a + +/usr/local/bin/platform_api_mgnt.sh install + +systemctl enable platform-modules-questone2.service +systemctl start platform-modules-questone2.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.init index 977cdac060..75edea4c00 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.init @@ -16,6 +16,16 @@ start) echo -n "Setting up board... " # Add driver to support HW + modprobe i2c-ismt + modprobe i2c-i801 + modprobe i2c-isch + modprobe i2c-mux + modprobe i2c-smbus + modprobe i2c-mux-gpio + modprobe i2c-mux-pca954x + modprobe ipmi_devintf + modprobe ipmi_si + modprobe i2c-dev modprobe ipmi_devintf modprobe ipmi_si @@ -28,14 +38,27 @@ start) devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` if [[ $devname == 'SMBus iSMT adapter at '* ]]; then echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-${devnum}/new_device - break + echo -n "/sys/bus/i2c/devices/i2c-${devnum}" > /tmp/eeprom_path.txt + break fi done + sleep 1 + # SONiC LED control policy + ipmitool raw 0x3a 0x0f 0x02 0x00 + # Set status led to green blinking 1Hz to indicate NOS take control + ipmitool raw 0x3a 0x0a 0x00 0x06 + # Set Alarm LED off + ipmitool raw 0x3a 0x0c 0x00 0x03 0x63 0x00 + # PSU is in default controlled by CPLD + echo "done." ;; stop) + if [ -f /tmp/eeprom_path.txt ]; then + echo 0x56 > `cat /tmp/eeprom_path.txt`/delete_device + fi echo "done." ;; diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install index 31fc4fd3bd..08923fedaf 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.install @@ -1,4 +1,7 @@ seastone2/cfg/seastone2-modules.conf etc/modules-load.d seastone2/systemd/platform-modules-seastone2.service lib/systemd/system seastone2/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-cel_seastone_2-r0 +seastone2/scripts/seastone2_platform_shutdown.sh usr/local/bin +seastone2/scripts/sensors usr/bin +seastone2/scripts/platform_sensors.py usr/local/bin services/platform_api/platform_api_mgnt.sh usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst index f232a2cac5..fc5257b984 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-seastone2.postinst @@ -1,5 +1,6 @@ depmod -a -systemctl enable platform-modules-seastone2.service -systemctl start platform-modules-seastone2.service /usr/local/bin/platform_api_mgnt.sh install + +systemctl enable platform-modules-seastone2.service +systemctl start platform-modules-seastone2.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init index eb003599ec..38895aff2b 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.init @@ -11,30 +11,105 @@ # Short-Description: Setup SilverStone board. ### END INIT INFO - case "$1" in start) echo -n "Setting up board... " - modprobe i2c-dev - modprobe baseboard-lpc - modprobe switchboard - modprobe mc24lc64t + modprobe i2c-i801 + modprobe i2c-isch + modprobe i2c-ismt + modprobe i2c-mux + modprobe i2c-smbus + modprobe coretemp modprobe ipmi_devintf + modprobe ipmi_si - # Instantiate TLV EEPROM device on I801 bus + modprobe i2c-dev + modprobe ipmi_devintf + modprobe baseboard-lpc + modprobe cls-i2c-mux-pca954x + modprobe cls-switchboard + modprobe xcvr-cls + modprobe switch_cpld + + sleep 1 + + for i in {0..3} + do + echo -2 > /sys/devices/pci0000:00/0000:00:1c.0/0000:09:00.0/ocores-i2c.3/i2c-3/3-007$i/idle_state + done + + # Instantiate TLV EEPROM device on I801 bus devname=`cat /sys/bus/i2c/devices/i2c-0/name` if [[ $devname == 'SMBus I801 adapter at '* ]]; then echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-0/new_device fi + + # Clear system cache decode-syseeprom --init 2> /dev/null & + sleep 1 + + # Attach switchboard CPLD i2c device + echo switch_cpld 0x30 > /sys/bus/i2c/devices/i2c-4/new_device + + # Attach optical Module EEPROM + # use optoe2 for SFP+. + for i in {1..2} + do + echo optoe2 0x50 > /sys/bus/i2c/devices/i2c-$i/new_device + done + + # use optoe3 for QSFP-DD. + for i in {10..41} + do + echo optoe3 0x50 > /sys/bus/i2c/devices/i2c-$i/new_device + done + + # SONiC LED control policy + ## Disable BMC LED control + ipmitool raw 0x3a 0x09 0x02 0x00 + ## Set status led to green blinking 1Hz to indicate NOS take control + ipmitool raw 0x3a 0x03 0x00 0x02 0x62 0xdd + ## Set Alarm LED off + ipmitool raw 0x3a 0x03 0x00 0x02 0x63 0xff + ## Set PSU HW control + ipmitool raw 0x3a 0x03 0x00 0x02 0x61 0x10 + ## Set FAN HW control + ipmitool raw 0x3a 0x03 0x00 0x02 0x65 0x10 + /bin/sh /usr/local/bin/platform_api_mgnt.sh init echo "done." ;; stop) + #TLV eeprom + if [ -d /sys/bus/i2c/devices/i2c-0/0-0056 ]; then + echo 0x56 > /sys/bus/i2c/devices/i2c-0/delete_device + fi + + #switchcpld i2c + if [ -d /sys/bus/i2c/devices/i2c-4/4-0030 ]; then + echo 0x30 > /sys/bus/i2c/devices/i2c-4/delete_device + fi + + #sfp+ module + for i in {1..2} + do + if [ -d /sys/bus/i2c/devices/i2c-$i/$i-0050 ]; then + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/delete_device + fi + done + + #qsfp-DD + for i in {10..41} + do + if [ -d /sys/bus/i2c/devices/i2c-$i/$i-0050 ]; then + echo 0x50 > /sys/bus/i2c/devices/i2c-$i/delete_device + fi + done + echo "done." ;; @@ -48,4 +123,4 @@ force-reload|restart) ;; esac -exit 0 \ No newline at end of file +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install index 73fa4b90a4..0a973ed8d6 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.install @@ -1,5 +1,6 @@ silverstone/scripts/sensors usr/bin silverstone/scripts/platform_sensors.py usr/local/bin +silverstone/scripts/silverstone_platform_shutdown.sh usr/local/bin silverstone/cfg/silverstone-modules.conf etc/modules-load.d silverstone/systemd/platform-modules-silverstone.service lib/systemd/system silverstone/modules/sonic_platform-1.0-py3-none-any.whl usr/share/sonic/device/x86_64-cel_silverstone-r0 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst index feb9cf45c2..f5dfe16c0b 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-silverstone.postinst @@ -1,5 +1,6 @@ depmod -a -systemctl enable platform-modules-silverstone.service -systemctl start platform-modules-silverstone.service /usr/local/bin/platform_api_mgnt.sh install + +systemctl enable platform-modules-silverstone.service +systemctl start platform-modules-silverstone.service diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/rules b/platform/broadcom/sonic-platform-modules-cel/debian/rules index 7c81e2496f..c161e72908 100755 --- a/platform/broadcom/sonic-platform-modules-cel/debian/rules +++ b/platform/broadcom/sonic-platform-modules-cel/debian/rules @@ -6,7 +6,7 @@ export KBUILD_EXTRA_SYMBOLS := /sonic/platform/pddf/i2c/Module.symvers.PDDF KVERSION ?= $(shell uname -r) KERNEL_SRC := /lib/modules/$(KVERSION) MOD_SRC_DIR:= $(shell pwd) -MODULE_DIRS:= dx010 haliburton silverstone seastone2 belgite +MODULE_DIRS:= dx010 haliburton silverstone seastone2 ds1000 questone2 %: dh $@ @@ -14,22 +14,13 @@ MODULE_DIRS:= dx010 haliburton silverstone seastone2 belgite override_dh_auto_build: (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules; \ - if [ $$mod = "seastone2" ]; then \ - cd $(MOD_SRC_DIR)/services/platform_api; \ - python3 -m build --wheel --no-isolation --outdir $(MOD_SRC_DIR)/$${mod}/modules; \ - continue; \ + if [ -d $(MOD_SRC_DIR)/$${mod}/pddf ]; then \ + cd $(MOD_SRC_DIR)/$${mod}/pddf; \ + else \ + cd $(MOD_SRC_DIR)/$${mod}; \ fi; \ - if [ $$mod = "belgite" ]; then \ - cd $(MOD_SRC_DIR); \ - if [ -d $(MOD_SRC_DIR)/$${mod}/pddf ]; then \ - cd $(MOD_SRC_DIR)/$${mod}/pddf; \ - python3 -m build --wheel --no-isolation --outdir $(MOD_SRC_DIR)/$${mod}/pddf; \ - echo "Finished making pddf whl package for $$mod"; \ - fi; \ - continue; \ - fi; \ - cd $(MOD_SRC_DIR)/$${mod}; \ - python3 -m build --wheel --no-isolation --outdir $(MOD_SRC_DIR)/$${mod}/modules; \ + python3 setup.py bdist_wheel -d $(MOD_SRC_DIR)/$${mod}/modules; \ + echo "Finished making sonic_platform whl package for $$mod"; \ done) override_dh_auto_install: @@ -46,7 +37,5 @@ override_dh_clean: dh_clean (for mod in $(MODULE_DIRS); do \ make -C $(KERNEL_SRC)/build M=$(MOD_SRC_DIR)/$${mod}/modules clean; \ - if [ -f $(MOD_SRC_DIR)/$${mod}/pddf/*.whl ]; then \ - rm -f $(MOD_SRC_DIR)/$${mod}/pddf/*.whl; \ - fi; \ + rm -f $(MOD_SRC_DIR)/$${mod}/modules/*.whl; \ done) diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/ds1000/modules/Makefile similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/belgite/modules/Makefile rename to platform/broadcom/sonic-platform-modules-cel/ds1000/modules/Makefile diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/ds1000/modules/mc24lc64t.c similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/belgite/modules/mc24lc64t.c rename to platform/broadcom/sonic-platform-modules-cel/ds1000/modules/mc24lc64t.c diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/modules/pddf_custom_psu.c b/platform/broadcom/sonic-platform-modules-cel/ds1000/modules/pddf_custom_psu.c similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/belgite/modules/pddf_custom_psu.c rename to platform/broadcom/sonic-platform-modules-cel/ds1000/modules/pddf_custom_psu.c diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/modules/pddf_custom_wdt.c b/platform/broadcom/sonic-platform-modules-cel/ds1000/modules/pddf_custom_wdt.c similarity index 96% rename from platform/broadcom/sonic-platform-modules-cel/belgite/modules/pddf_custom_wdt.c rename to platform/broadcom/sonic-platform-modules-cel/ds1000/modules/pddf_custom_wdt.c index 21ef0de9f3..a73a6f6eb1 100644 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/modules/pddf_custom_wdt.c +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/modules/pddf_custom_wdt.c @@ -86,7 +86,6 @@ struct cpld_wdt_private { struct platform_device *pdev; struct watchdog_device wddev; struct cdev cdev; - struct miscdevice mdev; bool suspended; struct wdt_data wdat; }; @@ -101,7 +100,7 @@ MODULE_PARM_DESC(timeout, "Start watchdog timer on module load with" " Zero (default) disables this feature."); static bool nowayout = WATCHDOG_NOWAYOUT; -module_param(nowayout, bool, 0644); +module_param(nowayout, bool, 0444); MODULE_PARM_DESC(nowayout, "Disable watchdog shutdown on close"); static unsigned int watchdog_get_timeleft(struct cpld_wdt_private *wdt) @@ -115,7 +114,7 @@ static unsigned int watchdog_get_timeleft(struct cpld_wdt_private *wdt) time = time << 8 | inb(WDT_TIMER_L_BIT_REG); time = time/1000; mutex_unlock(&wdt->wdat.lock); - + //pr_crit("Watchdog Get Timeleft:%u\n", time); return time; } static int watchdog_get_timeout(struct cpld_wdt_private *wdt) @@ -176,7 +175,7 @@ static int watchdog_ping(struct cpld_wdt_private *wdt) outb(WDT_START_FEED, WDT_FEED_REG); /* stop feed watchdog */ outb(WDT_STOP_FEED, WDT_FEED_REG); - + //pr_crit("Watchdog Ping\n"); mutex_unlock(&wdt->wdat.lock); return 0; @@ -199,7 +198,7 @@ static void watchdog_keepalive(struct cpld_wdt_private *wdt) val &= 0x1; /* start feed watchdog */ outb(val, WDT_FEED_REG); - + //pr_crit("Watchdog Keepalive\n"); mutex_unlock(&wdt->wdat.lock); return; } @@ -215,7 +214,7 @@ static int watchdog_start(struct cpld_wdt_private *wdt) outb(WDT_ENABLE, WDT_ENABLE_REG); outb(WDT_RESTART, WDT_PUNCH_REG); mutex_unlock(&wdt->wdat.lock); - + //pr_crit("Watchdog Start:Enable and PUNCH\n"); return 0; } @@ -227,7 +226,7 @@ static int watchdog_stop(struct cpld_wdt_private *wdt) mutex_lock(&wdt->wdat.lock); outb(WDT_DISABLE, WDT_ENABLE_REG); mutex_unlock(&wdt->wdat.lock); - + //pr_crit("Watchdog Stop\n"); return 0; } @@ -371,7 +370,7 @@ static int watchdog_open(struct inode *inode, struct file *file) { struct cpld_wdt_private *wdt; - wdt = container_of(file->private_data, struct cpld_wdt_private, mdev); + wdt = container_of(inode->i_cdev, struct cpld_wdt_private, cdev); /* If the watchdog is alive we don't need to start it again */ @@ -385,14 +384,14 @@ static int watchdog_open(struct inode *inode, struct file *file) wdt->wdat.expect_close = 0; - + file->private_data = wdt; return nonseekable_open(inode, file); } static int watchdog_release(struct inode *inode, struct file *file) { struct cpld_wdt_private *p; - p = container_of(file->private_data, struct cpld_wdt_private, mdev); + p = (struct cpld_wdt_private *)file->private_data; if(!p) return -EINVAL; @@ -424,7 +423,7 @@ static ssize_t watchdog_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct cpld_wdt_private *p; - p = container_of(file->private_data, struct cpld_wdt_private, mdev); + p = (struct cpld_wdt_private *)file->private_data; if(!p) return -EINVAL; @@ -481,7 +480,7 @@ static long watchdog_ioctl(struct file *file, unsigned int cmd, uarg.i = (int __user *)arg; struct cpld_wdt_private *p; - p = container_of(file->private_data, struct cpld_wdt_private, mdev); + p = (struct cpld_wdt_private *)file->private_data; if(!p) return -EINVAL; @@ -628,8 +627,8 @@ static int cpld_wdt_probe(struct platform_device *pdev) err = register_reboot_notifier(&watchdog_notifier); if (err) return err; - p->mdev = watchdog_miscdev; - err = misc_register(&p->mdev); + + err = misc_register(&watchdog_miscdev); if (err) { pr_err("cannot register miscdev on minor=%d\n", watchdog_miscdev.minor); @@ -673,7 +672,7 @@ static int cpld_wdt_remove(struct platform_device *pdev) sysfs_remove_group(&pdev->dev.kobj, &wdt_group); - misc_deregister(&p->mdev); + misc_deregister(&watchdog_miscdev); unregister_reboot_notifier(&watchdog_notifier); diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/setup.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/setup.py similarity index 94% rename from platform/broadcom/sonic-platform-modules-cel/belgite/pddf/setup.py rename to platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/setup.py index 159e266561..db095d2353 100644 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/setup.py +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/setup.py @@ -20,7 +20,7 @@ setup( 'License :: OSI Approved :: Apache Software License', 'Natural Language :: English', 'Operating System :: POSIX :: Linux', - 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.9', 'Topic :: Utilities', ], keywords='sonic SONiC platform PLATFORM', diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/__init__.py new file mode 100644 index 0000000000..d3c24cb008 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import platform diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/chassis.py similarity index 72% rename from platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/chassis.py rename to platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/chassis.py index ed2e339461..d09d6cfb53 100644 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/chassis.py +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/chassis.py @@ -5,21 +5,24 @@ ############################################################################# import os import time +import sys +import subprocess +import re try: from sonic_platform_pddf_base.pddf_chassis import PddfChassis from sonic_platform_pddf_base.pddf_eeprom import PddfEeprom from sonic_platform_base.chassis_base import ChassisBase - from sonic_platform.fan_drawer import FanDrawer + from sonic_platform.thermal import Thermal from sonic_platform.watchdog import Watchdog - import sys - import subprocess from sonic_py_common import device_info from sonic_platform_base.sfp_base import SfpBase except ImportError as e: raise ImportError(str(e) + "- required module not found") -NUM_COMPONENT = 2 +NUM_COMPONENTS = 4 +NUM_SENSORS = 4 +HW_REBOOT_CAUSE_FILE="/host/reboot-cause/hw-reboot-cause.txt" class Chassis(PddfChassis): """ @@ -31,17 +34,23 @@ class Chassis(PddfChassis): PddfChassis.__init__(self, pddf_data, pddf_plugin_data) (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() + self._watchdog = None + self._airflow_direction = None self.__initialize_components() - self.sfp_port_list = list(range(49, 56+1)) - for port_idx in self.sfp_port_list: - present = self.get_sfp(port_idx).get_presence() - self.sfp_status_dict[port_idx] = '1' if present else '0' + for sfp in self._sfp_list: + present = sfp.get_presence() + self.sfp_status_dict[sfp.index] = '1' if present else '0' + + # PDDF doesn't support CPU internal temperature sensor + # Hence it is created from chassis init override and + # handled appropriately in thermal APIs + self._thermal_list.append(Thermal(NUM_SENSORS)) def __initialize_components(self): from sonic_platform.component import Component - for index in range(0, NUM_COMPONENT): + for index in range(0, NUM_COMPONENTS): component = Component(index) self._component_list.append(component) @@ -99,12 +108,18 @@ class Chassis(PddfChassis): with open("/sys/devices/platform/cpld_wdt/reason", "r") as f: hw_reboot_cause = f.read().strip() - if hw_reboot_cause == "0x77": + if hw_reboot_cause == "0x99": + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'NPU overload reset' + elif hw_reboot_cause == "0x88": + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'CPU overload reset' + elif hw_reboot_cause == "0x77": reboot_cause = self.REBOOT_CAUSE_WATCHDOG description = 'Hardware Watchdog Reset' elif hw_reboot_cause == "0x66": reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER - description = 'GPIO Request Warm Reset' + description = 'GPIO Warm Reset' elif hw_reboot_cause == "0x55": reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER description = 'CPU Cold Reset' @@ -112,14 +127,29 @@ class Chassis(PddfChassis): reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE description = 'CPU Warm Reset' elif hw_reboot_cause == "0x33": - reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER description = 'Soft-Set Cold Reset' elif hw_reboot_cause == "0x22": - reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER description = 'Soft-Set Warm Reset' elif hw_reboot_cause == "0x11": reboot_cause = self.REBOOT_CAUSE_POWER_LOSS description = 'Power Loss' + elif hw_reboot_cause == "0x00": + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'Cold Powercycle' + if os.path.isfile(HW_REBOOT_CAUSE_FILE): + with open(HW_REBOOT_CAUSE_FILE) as hw_cause_file: + reboot_info = hw_cause_file.readline().rstrip('\n') + match = re.search(r'Reason:(.*),Time:(.*)', reboot_info) + if match is not None: + if match.group(1) == 'temp_fatal': + description = 'Fatal temperature trip [Time:{}]'.format(match.group(2)) + elif match.group(1) == 'temp_critical': + description = 'Critical temperature reboot [Time:{}]'.format(match.group(2)) + elif match.group(1) == 'system': + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'System cold reboot' else: reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE description = 'Unkown Reason' @@ -149,7 +179,10 @@ class Chassis(PddfChassis): 'amber': "STATUS_LED_COLOR_AMBER", 'off': "STATUS_LED_COLOR_OFF" } - return self.set_system_led("SYS_LED", color_dict.get(color, "STATUS_LED_COLOR_OFF")) + if color == self.get_system_led("SYS_LED"): + return False + else: + return self.set_system_led("SYS_LED", color_dict.get(color, "STATUS_LED_COLOR_OFF")) def get_status_led(self): return self.get_system_led("SYS_LED") @@ -224,13 +257,14 @@ class Chassis(PddfChassis): time_period = timeout/float(1000) #Convert msecs to secs while time.time() < (start_time + time_period) or timeout == 0: - for port_idx in self.sfp_port_list: + for sfp in self._sfp_list: + port_idx = sfp.index if self.sfp_status_dict[port_idx] == SFP_REMOVED and \ - self.get_sfp(port_idx).get_presence() == SFP_PRESENT: + sfp.get_presence() == SFP_PRESENT: sfp_dict[port_idx] = SFP_INSERTED self.sfp_status_dict[port_idx] = SFP_INSERTED elif self.sfp_status_dict[port_idx] == SFP_INSERTED and \ - self.get_sfp(port_idx).get_presence() == SFP_ABSENT: + sfp.get_presence() == SFP_ABSENT: sfp_dict[port_idx] = SFP_REMOVED self.sfp_status_dict[port_idx] = SFP_REMOVED @@ -240,3 +274,21 @@ class Chassis(PddfChassis): time.sleep(0.5) return True, {'sfp':{}} # Timeout + + def get_airflow_direction(self): + if self._airflow_direction == None: + try: + vendor_extn = self._eeprom.get_vendor_extn() + airflow_type = vendor_extn.split()[2][2:4] # Either 0xFB or 0xBF + if airflow_type == 'FB': + direction = 'exhaust' + elif airflow_type == 'BF': + direction = 'intake' + else: + direction = 'N/A' + except (AttributeError, IndexError): + direction = 'N/A' + + self._airflow_direction = direction + + return self._airflow_direction diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/component.py similarity index 50% rename from platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/component.py rename to platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/component.py index 3b68c5759b..62ba924bda 100644 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/component.py +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/component.py @@ -9,7 +9,7 @@ ############################################################################# import subprocess -import time +import re try: from sonic_platform_base.component_base import ComponentBase @@ -17,11 +17,14 @@ try: except ImportError as e: raise ImportError(str(e) + "- required module not found") -SWCPLD_VERSION_PATH = ['i2cget', '-y', '-f', '2', '0x32', '0'] -BIOS_VERSION_PATH = ['dmidecode', '-s', 'bios-version'] -COMPONENT_NAME_LIST = ["SWCPLD", "BIOS"] -COMPONENT_DES_LIST = ["Used for managing the chassis and SFP+ ports (49-56)", - "Basic Input/Output System"] +COMPONENT_NAME = 0 +COMPONENT_DESC = 1 +COMPONENT_VER_CMD = 2 +COMPONENT_VER_FN = 3 +BIOS_VERSION_CMD = ['dmidecode', '-s', 'bios-version'] +ONIE_VERSION_CMD = ['cat', '/host/machine.conf'] +SWCPLD_VERSION_CMD = ['i2cget', '-y', '-f', '2', '0x32', '0'] +SSD_VERSION_CMD = ['smartctl', '-i', '/dev/sda'] class Component(ComponentBase): @@ -30,16 +33,21 @@ class Component(ComponentBase): DEVICE_TYPE = "component" def __init__(self, component_index): + self.component_list = [["BIOS", "Basic Input/Output System", BIOS_VERSION_CMD, self.__get_cmd_output],\ + ["ONIE", "Open Network Install Environment", ONIE_VERSION_CMD, self.__get_onie_version],\ + ["CPLD SW", "CPLD for board functions, watchdog and port control SFP(49-56)", SWCPLD_VERSION_CMD, self.__get_cpld_version],\ + ["SSD", "Solid State Drive - {}", SSD_VERSION_CMD, self.__get_ssd_version]] + ComponentBase.__init__(self) self.index = component_index self.name = self.get_name() - def __get_bios_version(self): - # Retrieves the BIOS firmware version + def __get_cmd_output(self): + cmd = self.component_list[self.index][COMPONENT_VER_CMD] version = "N/A" try: - p = subprocess.Popen(BIOS_VERSION_PATH, stdout=subprocess.PIPE, universal_newlines=True) + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True) data = p.communicate() version = data[0].strip() except IOError: @@ -47,14 +55,34 @@ class Component(ComponentBase): return version + def __get_onie_version(self): + version = "N/A" + + ret = re.search(r"(?<=onie_version=).+[^\n]", self.__get_cmd_output()) + if ret != None: + version = ret.group(0) + + return version + + def __get_ssd_version(self): + version = "N/A" + + ret = re.search(r"Firmware Version: +(.*)[^\\]", self.__get_cmd_output()) + if ret != None: + try: + version = ret.group(1) + except (IndexError): + pass + + return version + def __get_cpld_version(self): version = "N/A" + try: - p = subprocess.Popen(SWCPLD_VERSION_PATH, stdout=subprocess.PIPE, universal_newlines=True) - data = p.communicate() - ver = int(data[0].strip(), 16) + ver = int(self.__get_cmd_output(), 16) version = "{0}.{1}".format(ver >> 4, ver & 0x0F) - except (IOError, ValueError): + except (ValueError): pass return version @@ -65,7 +93,19 @@ class Component(ComponentBase): Returns: A string containing the name of the component """ - return COMPONENT_NAME_LIST[self.index] + return self.component_list[self.index][COMPONENT_NAME] + + def __get_ssd_desc(self, desc_format): + description = "N/A" + + ret = re.search(r"Device Model: +(.*)[^\\]", self.__get_cmd_output()) + if ret != None: + try: + description = desc_format.format(ret.group(1)) + except (IndexError): + pass + + return description def get_description(self): """ @@ -73,7 +113,11 @@ class Component(ComponentBase): Returns: A string containing the description of the component """ - return COMPONENT_DES_LIST[self.index] + # For SSD get the model name from device + if self.get_name() == "SSD": + return self.__get_ssd_desc(self.component_list[self.index][COMPONENT_DESC]) + + return self.component_list[self.index][COMPONENT_DESC] def get_firmware_version(self): """ @@ -82,12 +126,8 @@ class Component(ComponentBase): string: The firmware versions of the module """ fw_version = None - - if self.name == "BIOS": - fw_version = self.__get_bios_version() - elif "CPLD" in self.name: - fw_version = self.__get_cpld_version() - + fw_version = self.component_list[self.index][COMPONENT_VER_FN]() + return fw_version def install_firmware(self, image_path): diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/eeprom.py similarity index 83% rename from platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/eeprom.py rename to platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/eeprom.py index bc1ef6420b..3f8488091c 100644 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/eeprom.py +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/eeprom.py @@ -58,18 +58,11 @@ class Eeprom(PddfEeprom): else: name, value = self.decoder(None, tlv) - self.eeprom_tlv_dict[code] = value + self.eeprom_tlv_dict[code] = value.strip() if (eeprom[tlv_index]) == self._TLV_CODE_CRC_32: break tlv_index += (eeprom[tlv_index+1]) + 2 - def vendor_ext_str(self): - """ - :return: the direction of fan(FB or BF, string) - """ - (is_valid, results) = self.get_tlv_field(self.eeprom_data, self._TLV_CODE_VENDOR_EXT) - if not is_valid: - return "N/A" - return str(hex(int(results[2][2]))).replace("0x", "").upper() - # Provide the functions/variables below for which implementation is to be overwritten + def get_vendor_extn(self): + return self.eeprom_tlv_dict.get('0xFD', 'N/A') diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/fan.py new file mode 100644 index 0000000000..9fd7433b9b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/fan.py @@ -0,0 +1,134 @@ +try: + from sonic_platform_pddf_base.pddf_fan import PddfFan + import subprocess +except ImportError as e: + raise ImportError(str(e) + "- required module not found") +# ------------------------------------------------------------------ +# HISTORY: +# 5/1/2022 (A.D.) +# add function:set_status_led, +# Solve the problem that when a fan is pulled out, the Fan LED on the front panel is still green Issue-#11525 +# ------------------------------------------------------------------ + +MIN_SPEED = 40 # Percentage + +class Fan(PddfFan): + """PDDF Platform-Specific Fan class""" + + def __init__(self, tray_idx, fan_idx=0, pddf_data=None, pddf_plugin_data=None, is_psu_fan=False, psu_index=0): + # idx is 0-based + PddfFan.__init__(self, tray_idx, fan_idx, pddf_data, pddf_plugin_data, is_psu_fan, psu_index) + + self.max_speed_rpm = 28600 #Max RPM from FAN spec + + + def get_presence(self): + if not self.is_psu_fan: + # FANs on Ds1000 are all Fixed and present + return True + + #For PSU, FAN must be present when PSU is present + try: + cmd = ['i2cget', '-y', '-f', '0x2', '0x32', '0x41'] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True) + data = p.communicate() + status = int(data[0].strip(), 16) + if (self.fans_psu_index == 1 and (status & 0x10) == 0) or \ + (self.fans_psu_index == 2 and (status & 0x20) == 0): + return True + except (IOError, ValueError): + pass + + def get_status(self): + if not self.is_psu_fan: + if not self.get_presence(): + return False + + # FANs must not be operated below MIN_SPEED + target_speed = self.get_target_speed() + if target_speed < MIN_SPEED: + return False + + # FANs target speed and actual speed must + # be within specified tolerance limits + current_speed = self.get_speed() + speed_tolerance = self.get_speed_tolerance() + if abs(target_speed - current_speed) > speed_tolerance: + return False + + return True + + return super().get_status() + + # Override get_speed as PDDF retrieves the speed from the + # set PWM value which is actually the target fan speed + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + if self.is_psu_fan: + return super().get_speed() + + # Percentage of current FAN speed against the max FAN speed + return round(super().get_speed_rpm() * 100 / self.max_speed_rpm) + + def get_direction(self): + """ + Retrieves the direction of fan + + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + if self.is_psu_fan: + # Ds1000 PSU module only has EXHAUST fan + return "exhaust" + + return super().get_direction() + + def get_status_led(self): + """ + Gets the state of the fan status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.is_psu_fan: + return "N/A" + + return super().get_status_led() + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + + Args: + color: A string representing the color with which to set the + fan module status LED + + Returns: + bool: True if status LED state is set successfully, False if not + """ + if self.is_psu_fan: + return False + + if self.get_status_led() == color: + return True + + color_dict = { + 'green': "STATUS_LED_COLOR_GREEN", + 'amber': "STATUS_LED_COLOR_AMBER", + } + color = color_dict.get(color, "STATUS_LED_COLOR_AMBER") + + return super().set_status_led(color) + + def get_name(self): + if self.is_psu_fan: + return "PSU {} Fan {}".format(self.fans_psu_index, self.fan_index) + else: + return "Fan {}".format(self.fantray_index) diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/fan_drawer.py similarity index 92% rename from platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/fan_drawer.py rename to platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/fan_drawer.py index ac80aad4b1..b50226380b 100644 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/fan_drawer.py +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/fan_drawer.py @@ -31,3 +31,6 @@ class FanDrawer(PddfFanDrawer): def get_model(self): model = "Unknown" return model + + def get_name(self): + return "Drawer {0}".format(self.fantray_index) diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/pcie.py new file mode 100644 index 0000000000..0f8bc08303 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/pcie.py @@ -0,0 +1,15 @@ +# +# pcie_base.py +# +# Abstract base class for implementing platform-specific +# PCIE functionality for SONiC +# + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError (str(e) + " - required module not found") + +class Pcie(PcieUtil): + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/platform.py similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/platform.py rename to platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/platform.py diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/psu.py similarity index 61% rename from platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/psu.py rename to platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/psu.py index f1047bed74..a89682363d 100644 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/psu.py +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/psu.py @@ -71,3 +71,38 @@ class Psu(PddfPsu): e.g. 12.1 """ return 11.4 + + def get_voltage(self): + """ + Retrieves current PSU voltage output + + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + # When AC power is not plugged into one of the PSU, the FAN of + # that PSU is driven using the power from the alternate PSU and + # because of this the PSU VOUT might read a small voltage value + # and it is misleading. Therefore the PSU VOUT is fetched from + # HW only when PSU status is OK + if self.get_status(): + return super().get_voltage() + + return 0.0 + + def get_status_led(self): + """ + Gets the state of the PSU status LED + + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + # In Ds1000 PSU LED is controlled by the PSU firmware, so soft + # simulating the LED in a generic way based on the PSU status + if self.get_presence(): + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return self.STATUS_LED_COLOR_AMBER + + return "N/A" diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/sfp.py new file mode 100644 index 0000000000..9187edb1fd --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/sfp.py @@ -0,0 +1,36 @@ +try: + from sonic_platform_pddf_base.pddf_sfp import PddfSfp +except ImportError as e: + raise ImportError (str(e) + "- required module not found") + + +class Sfp(PddfSfp): + """ + PDDF Platform-Specific Sfp class + """ + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None): + self.index = index+1 + PddfSfp.__init__(self, index, pddf_data, pddf_plugin_data) + + # Provide the functions/variables below for which implementation is to be overwritten + + def get_error_description(self): + """ + Retrives the error descriptions of the SFP module + Returns: + String that represents the current error descriptions of vendor specific errors + In case there are multiple errors, they should be joined by '|', + like: "Bad EEPROM|Unsupported cable" + """ + if not self.get_presence(): + return self.SFP_STATUS_UNPLUGGED + return self.SFP_STATUS_OK + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + + SFP+ don't support reset, so raise the error of NotImplemented + """ + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/thermal.py new file mode 100644 index 0000000000..b17dfa4457 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/thermal.py @@ -0,0 +1,105 @@ +try: + from sonic_platform_pddf_base.pddf_thermal import PddfThermal +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +import subprocess + +HIGH_THRESHOLD = 0 +LOW_THRESHOLD = 1 +HIGH_CRIT_THRESHOLD = 2 +LOW_CRIT_THRESHOLD = 3 + +NUM_SENSORS = 4 +CPU_SENSOR_STR = "CPU Internal Temp" +thermal_limits = { + # : , , , + 'Front Right Temp': [50.0, None, None, None], + 'Front Left Temp': [50.0, None, None, None], + 'Rear Right Temp': [50.0, None, None, None], + 'ASIC External Temp': [100.0, None, 105.0, None], + CPU_SENSOR_STR: [88.0, None, 91.0, None] +} + +class Thermal(PddfThermal): + """PDDF Platform-Specific Thermal class""" + + def __init__(self, index, pddf_data=None, pddf_plugin_data=None, is_psu_thermal=False, psu_index=0): + # PDDF doesn't support CPU internal temperature sensor + # Hence it is created from chassis init override and + # handled appropriately in thermal APIs + self.thermal_index = index + 1 + self.is_psu_thermal = is_psu_thermal + if self.thermal_index <= NUM_SENSORS: + PddfThermal.__init__(self, index, pddf_data, pddf_plugin_data, is_psu_thermal, psu_index) + # Provide the functions/variables below for which implementation is to be overwritten + + def get_name(self): + if self.thermal_index <= NUM_SENSORS: + return super().get_name() + + return CPU_SENSOR_STR + + def get_temperature(self): + if self.thermal_index <= NUM_SENSORS: + return super().get_temperature() + + temperature = 0.0 + cmd = ['cat', '/sys/devices/platform/coretemp.0/hwmon/hwmon1/temp1_input'] + try: + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True) + data = p.communicate() + temperature = int(data[0].strip())/1000.0 + except (IOError, ValueError): + pass + + return temperature + + def get_low_threshold(self): + thermal_limit = thermal_limits.get(self.get_name(), None) + if thermal_limit != None: + return thermal_limit[LOW_THRESHOLD] + + return None + + def __get_psu_high_threshold(self): + thermal_limit = None + try: + cmd = ['i2cget', '-y', '-f', '4', str(0x58 + (self.thermals_psu_index - 1)), '0x51', 'w'] + p = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True) + data = p.communicate() + thermal_limit = int(data[0].strip(), 16) + except (IOError, ValueError): + pass + + return thermal_limit + + def get_high_threshold(self): + if self.is_psu_thermal: + return self.__get_psu_high_threshold() + + thermal_limit = thermal_limits.get(self.get_name(), None) + if thermal_limit != None: + return thermal_limit[HIGH_THRESHOLD] + + return None + + def get_low_critical_threshold(self): + thermal_limit = thermal_limits.get(self.get_name(), None) + if thermal_limit != None: + return thermal_limit[LOW_CRIT_THRESHOLD] + + return None + + def get_high_critical_threshold(self): + thermal_limit = thermal_limits.get(self.get_name(), None) + if thermal_limit != None: + return thermal_limit[HIGH_CRIT_THRESHOLD] + + return None + + def set_high_threshold(self, temperature): + raise NotImplementedError + + def set_low_threshold(self, temperature): + raise NotImplementedError diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/watchdog.py similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/belgite/pddf/sonic_platform/watchdog.py rename to platform/broadcom/sonic-platform-modules-cel/ds1000/pddf/sonic_platform/watchdog.py diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/ds1000_platform_shutdown.sh b/platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/ds1000_platform_shutdown.sh new file mode 100755 index 0000000000..a1ea8ccbe4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/ds1000_platform_shutdown.sh @@ -0,0 +1,26 @@ +#!/bin/bash +REBOOT_CAUSE_DIR="/host/reboot-cause" +HW_REBOOT_CAUSE_FILE="/host/reboot-cause/hw-reboot-cause.txt" +REBOOT_TIME=$(date) + +if [ $# -ne 1 ]; then + echo "Require reboot type" + exit 1 +fi + +if [ ! -d "$REBOOT_CAUSE_DIR" ]; then + mkdir $REBOOT_CAUSE_DIR +fi + +echo "Reason:$1,Time:${REBOOT_TIME}" > ${HW_REBOOT_CAUSE_FILE} + +# Best effort to write buffered data onto the disk +sync ; sync ; sync ; sleep 3 + +# CPLD CPU cold power-cycle +i2cset -f -y 2 0x32 0x18 0x0 + +# System should reboot by now and avoid the script returning to caller +sleep 10 + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/pddf_post_device_create.sh b/platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/pddf_post_device_create.sh new file mode 100755 index 0000000000..9fd8364e23 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/pddf_post_device_create.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +# Enable FAN WDT +sudo i2cset -y -f 2 0x32 0x30 0x01 + +# Set all FAN speed to 100% +sudo i2cset -y -f 2 0x32 0x32 0xff +sudo i2cset -y -f 2 0x32 0x36 0xff +sudo i2cset -y -f 2 0x32 0x3a 0xff + +# Set FAN LED status to GREEN +sudo i2cset -y -f 2 0x32 0x33 0x2 +sudo i2cset -y -f 2 0x32 0x37 0x2 +sudo i2cset -y -f 2 0x32 0x3b 0x2 + +# Set Alarm LED status to OFF, since it is unused in SONiC +sudo i2cset -y -f 2 0x32 0x44 0x00 + +# Set SYS LED status to GREEN +sudo i2cset -y -f 2 0x32 0x43 0xec + +echo -2 | tee /sys/bus/i2c/drivers/pca954x/*-00*/idle_state diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/scripts/pddf_pre_driver_install.sh b/platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/pddf_pre_driver_install.sh similarity index 100% rename from platform/broadcom/sonic-platform-modules-cel/belgite/scripts/pddf_pre_driver_install.sh rename to platform/broadcom/sonic-platform-modules-cel/ds1000/scripts/pddf_pre_driver_install.sh diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/service/ds1000-fan-control.service b/platform/broadcom/sonic-platform-modules-cel/ds1000/service/ds1000-fan-control.service new file mode 100644 index 0000000000..7269080b53 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/service/ds1000-fan-control.service @@ -0,0 +1,17 @@ +[Unit] +Description=Ds1000 Fan Control service +After=pddf-platform-init.service +Requires=pddf-platform-init.service +BindsTo=pddf-platform-init.service + +[Service] +Type=simple +ExecStart=/usr/local/bin/ds1000_fanctld.py +KillSignal=SIGTERM +SuccessExitStatus=0 + +# Resource Limitations +LimitCORE=infinity + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-cel/belgite/systemd/pddf-platform-init.service b/platform/broadcom/sonic-platform-modules-cel/ds1000/systemd/pddf-platform-init.service similarity index 81% rename from platform/broadcom/sonic-platform-modules-cel/belgite/systemd/pddf-platform-init.service rename to platform/broadcom/sonic-platform-modules-cel/ds1000/systemd/pddf-platform-init.service index 249fa2e897..becd98ea60 100644 --- a/platform/broadcom/sonic-platform-modules-cel/belgite/systemd/pddf-platform-init.service +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/systemd/pddf-platform-init.service @@ -1,6 +1,6 @@ [Unit] Description=PDDF module and device initialization service -Before=pmon.service watchdog-control.service +Before=pmon.service watchdog-control.service ds1000-fan-control.service Before=opennsl-modules.service DefaultDependencies=no diff --git a/platform/broadcom/sonic-platform-modules-cel/ds1000/utils/ds1000_fanctld.py b/platform/broadcom/sonic-platform-modules-cel/ds1000/utils/ds1000_fanctld.py new file mode 100755 index 0000000000..7d10a734da --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/ds1000/utils/ds1000_fanctld.py @@ -0,0 +1,346 @@ +#!/usr/bin/python3 +# +# Copyright (C) Celestica Technology 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 +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +# ------------------------------------------------------------------ +# HISTORY: +# 9/16/2021 (A.D.) +# ------------------------------------------------------------------ + +try: + import os + import sys + import getopt + import subprocess + import re + import time + import signal + from sonic_platform import platform + from sonic_py_common import daemon_base +except ImportError as e: + raise ImportError('%s - required module not found' % repr(e)) + +# Constants +NOMINAL_TEMP = 30 # degree C +MODULE_NAME = 'ds1000fanctld' +SP_LOW_TEMP = 0 +SP_HIGH_TEMP = 1 +SP_CRITICAL_TEMP = 2 +SP_FATAL_TEMP = 3 +SP_REF_TEMP = 4 +SP_FAN_SPEED = 5 +SP_VALIDATE = 6 + +# Daemon control platform specific constants +PDDF_INIT_WAIT = 30 #secs +POLL_INTERVAL = 10 #secs +CRITICAL_DURATION = 120 #secs +CRITICAL_LOG_INTERVAL = 20 #every 'n' secs +FAN_DUTY_MIN = 40 # percentage +FAN_DUTY_MAX = 100 #percentage +TEMP_HYST = 3 # degree C +NUM_FANS = 3 + +# Validation functions +def valid_if_exhaust(fan_dir): + if fan_dir == "EXHAUST": + return True + + return False + +def valid_if_intake(fan_dir): + if fan_dir == "INTAKE": + return True + + return False + +def valid_always(fan_dir): + return True + +def valid_never(fan_dir): + return False + +# Core data for Thermal FAN speed evaluation +# {: [low_temp, high_temp, critical_temp, fatal_temp, current_temp, fanspeed, validate_function]} +SENSOR_PARAM = { + 'Front Right Temp': [34, 47, None, None, NOMINAL_TEMP, FAN_DUTY_MIN, valid_if_exhaust], + 'Front Left Temp': [None, None, None, None, NOMINAL_TEMP, FAN_DUTY_MIN, valid_never], + 'Rear Right Temp': [34, 47, None, None, NOMINAL_TEMP, FAN_DUTY_MIN, valid_if_intake], + 'ASIC External Temp': [54, 69, 105, 110, NOMINAL_TEMP, FAN_DUTY_MIN, valid_always], + 'CPU Internal Temp': [69, 84, 91, 94, NOMINAL_TEMP, FAN_DUTY_MIN, valid_always] +} + +class Ds1000FanControl(daemon_base.DaemonBase): + global MODULE_NAME + global SENSOR_PARAM + + def __init__(self, log_level): + + str_to_log_level = { + 'ERROR' : self.LOG_PRIORITY_ERROR, \ + 'WARNING' : self.LOG_PRIORITY_WARNING, \ + 'NOTICE': self.LOG_PRIORITY_NOTICE, \ + 'INFO': self.LOG_PRIORITY_INFO, \ + 'DEBUG': self.LOG_PRIORITY_DEBUG + } + self.fan_list = [] + self.thermal_list = [] + + super(Ds1000FanControl, self).__init__(MODULE_NAME) + if log_level is not None: + self.set_min_log_priority(str_to_log_level.get(log_level)) + self.log_info("Forcing to loglevel {}".format(log_level)) + self.log_info("Starting up...") + + self.log_debug("Waiting {} secs for PDDF driver initialization".format(PDDF_INIT_WAIT)) + time.sleep(PDDF_INIT_WAIT) + + try: + self.critical_period = 0 + self.platform_chassis = platform.Platform().get_chassis() + + # Fetch FAN info + self.fan_list = self.platform_chassis.get_all_fans() + if len(self.fan_list) != NUM_FANS: + self.log_error("Fans detected({}) is not same as expected({}), so exiting..."\ + .format(len(self.fan_list), NUM_FANS)) + sys.exit(1) + + self.fan_dir = self.fan_list[0].get_direction() + self.log_debug("Fans direction is {}".format(self.fan_dir)) + + # Fetch THERMAL info + self.thermal_list = self.platform_chassis.get_all_thermals() + if len(self.thermal_list) != len(SENSOR_PARAM): + self.log_error("Thermals detected({}) is not same as expected({}), so exiting..."\ + .format(len(self.thermal_list), len(SENSOR_PARAM))) + sys.exit(1) + + # Initialize the thermal temperature dict + # {: [thermal_temp, fanspeed]} + for thermal in self.thermal_list: + thermal_name = thermal.get_name() + SENSOR_PARAM[thermal_name][SP_REF_TEMP] = thermal.get_temperature() + + except Exception as e: + self.log_error("Failed to init Ds1000FanControl due to {}, so exiting...".format(repr(e))) + sys.exit(1) + + # Signal handler + def signal_handler(self, sig, frame): + if sig == signal.SIGHUP: + self.log_notice("Caught SIGHUP - ignoring...") + elif sig == signal.SIGINT: + self.log_warning("Caught SIGINT - Setting all FAN speed to max({}%) and exiting... ".format(FAN_DUTY_MAX)) + self.set_all_fan_speed(FAN_DUTY_MAX) + sys.exit(0) + elif sig == signal.SIGTERM: + self.log_warning("Caught SIGTERM - Setting all FAN speed to max({}%) and exiting... ".format(FAN_DUTY_MAX)) + self.set_all_fan_speed(FAN_DUTY_MAX) + sys.exit(0) + else: + self.log_notice("Caught unhandled signal '" + sig + "'") + + + @staticmethod + def is_fan_operational(fan): + if fan.get_presence() and fan.get_status(): + return True + + return False + + @staticmethod + def get_speed_from_min_max(cur_temp, min_temp, max_temp, min_speed, max_speed): + if cur_temp <= min_temp: + speed = min_speed + elif cur_temp >= max_temp: + speed = max_speed + else: + multiplier = (max_speed - min_speed) / (max_temp - min_temp) + speed = int(((cur_temp - min_temp) * multiplier) + min_speed) + + return speed + + def thermal_shutdown(self, reason): + cmd = ['/usr/local/bin/ds1000_platform_shutdown.sh', reason] + + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, universal_newlines=True) + proc.communicate() + if proc.returncode == 0: + return True + else: + self.log_error("Thermal {} shutdown failed with errorno {}"\ + .format(reason, proc.returncode)) + return False + + def get_fan_speed_from_thermals(self): + prominent_speed = FAN_DUTY_MIN + is_critical = False + + for thermal in self.thermal_list: + speed = prominent_speed + thermal_name = thermal.get_name() + thermal_temp = thermal.get_temperature() + thermal_info = SENSOR_PARAM[thermal_name] + thermal_ref = thermal_info[SP_REF_TEMP] + thermal_low = thermal_info[SP_LOW_TEMP] + thermal_high = thermal_info[SP_HIGH_TEMP] + thermal_critical = thermal_info[SP_CRITICAL_TEMP] + thermal_fatal = thermal_info[SP_FATAL_TEMP] + + if thermal_info[SP_VALIDATE](self.fan_dir): + self.log_debug("{} temperature is {}C".format(thermal_name, thermal_temp)) + if thermal_temp <= thermal_low: + SENSOR_PARAM[thermal_name][SP_REF_TEMP] = thermal_low + speed = FAN_DUTY_MIN + elif thermal_temp >= thermal_high: + SENSOR_PARAM[thermal_name][SP_REF_TEMP] = thermal_high + speed = FAN_DUTY_MAX + if thermal_fatal and thermal_temp >= thermal_fatal: + # Double check since immediate cold power-cycle + # is an expensive operation in field + if thermal.get_temperature() >= thermal_fatal: + self.log_warning("'{}' temperature ({}C) hit fatal limit ({}C)."\ + " Triggering immediate cold power-cycle"\ + .format(thermal_name, thermal_temp, thermal_fatal)) + self.thermal_shutdown('temp_fatal') + sys.exit(0) + else: + self.log_warning("'{}' temperature ({}C) hit fatal limit ({}C) intermittently"\ + .format(thermal_name, thermal_temp, thermal_fatal)) + elif thermal_critical and thermal_temp >= thermal_critical: + if self.critical_period < CRITICAL_DURATION: + if self.critical_period % CRITICAL_LOG_INTERVAL == 0: + self.log_warning("'{}' temperature ({}C) hit critical limit ({}C)."\ + " Triggering cold power-cycle in {} seconds"\ + .format(thermal_name, thermal_temp, thermal_critical,\ + (CRITICAL_DURATION - self.critical_period))) + is_critical = True + else: + self.log_warning("'{}' temperature ({}C) is in critical limit ({}C) for more"\ + " than {} seconds. Triggering cold power-cycle now"\ + .format(thermal_name, thermal_temp, thermal_critical,\ + CRITICAL_DURATION)) + self.thermal_shutdown('temp_critical') + sys.exit(0) + + else: + if thermal_temp > thermal_ref: + SENSOR_PARAM[thermal_name][SP_REF_TEMP] = thermal_temp + speed = self.get_speed_from_min_max(thermal_temp, thermal_low, thermal_high,\ + FAN_DUTY_MIN, FAN_DUTY_MAX) + elif thermal_ref - thermal_temp >= TEMP_HYST: + SENSOR_PARAM[thermal_name][SP_REF_TEMP] = thermal_temp + 1 + speed = self.get_speed_from_min_max(thermal_temp + 1, thermal_low, thermal_high,\ + FAN_DUTY_MIN, FAN_DUTY_MAX) + else: + speed = SENSOR_PARAM[thermal_name][SP_FAN_SPEED] + + self.log_debug("{} thermal speed is {}%".format(thermal_name, speed)) + SENSOR_PARAM[thermal_name][SP_FAN_SPEED] = speed + prominent_speed = max(prominent_speed, speed) + + if is_critical: + self.critical_period = self.critical_period + POLL_INTERVAL + elif self.critical_period > 0: + self.critical_period = 0 + self.log_notice("All thermals are now below critical limit."\ + " System cold power-cycle is now cancelled") + + self.log_debug("Prominent thermal speed is {}%".format(prominent_speed)) + + return prominent_speed + + def set_all_fan_speed(self, speed): + for fan in self.fan_list: + fan_name = fan.get_name() + try: + if fan.set_speed(speed): + self.log_debug("Set {} speed to {}%".format(fan_name, speed)) + else: + self.log_error("Set '{}' to speed {}% failed".format(fan_name, speed)) + except Exception as e: + self.log_error("Set '{}' to speed {}% failed due to {}".format(fan_name, speed, repr(e))) + + return False + + def run(self): + while True: + num_good_fans = 0 + dir_mismatch = False + for fan in self.fan_list: + if self.is_fan_operational(fan): + num_good_fans = num_good_fans + 1 + else: + self.log_notice("FAN '{}' is broken or not inserted".format(fan.get_name())) + + if self.fan_dir is None: + self.fan_dir = fan.get_direction() + elif self.fan_dir != fan.get_direction(): + dir_mismatch = True + self.log_debug("{} FANs are operational, there is{}direction mismatch"\ + .format('All' if num_good_fans == len(self.fan_list) else num_good_fans, + ' ' if dir_mismatch else ' no ')) + + # Always evaluate the thermals irrespective of the FAN state + speed = self.get_fan_speed_from_thermals() + + if dir_mismatch: + self.log_warning("Some FANs have incompatible direction. Please replace FANs immediately") + else: + if num_good_fans == len(self.fan_list): # Good FANs is equal to number of FANs + self.set_all_fan_speed(speed) + else: + if not num_good_fans: # None of the FANs are operational + self.log_warning("Overheating hazard!! All FANs are broken or not inserted") + else: + self.log_warning("Some FANs are broken or not inserted") + self.set_all_fan_speed(FAN_DUTY_MAX) + + time.sleep(POLL_INTERVAL) + +def main(argv): + log_level = None + valid_log_levels = ['ERROR', 'WARNING', 'NOTICE', 'INFO', 'DEBUG'] + + if len(sys.argv) != 1: + try: + opts, args = getopt.getopt(argv, 'hdl', ['log-level=']) + except getopt.GetoptError: + print('Usage: %s [-d] [-l ]' % sys.argv[0]) + sys.exit(1) + for opt, arg in opts: + if opt == '-h': + print('Usage: %s [-d] [-l ]\nlog_level - ERROR, WARNING, NOTICE, INFO, DEBUG' % sys.argv[0]) + sys.exit(1) + elif opt in ('-l', '--log-level'): + if log_level not in valid_log_levels: + print('Invalid log level %s' % arg) + sys.exit(1) + elif opt == '-d': + log_level = 'DEBUG' + + fanctl = Ds1000FanControl(log_level) + + fanctl.log_debug("Start daemon main loop") + # Loop forever, doing something useful hopefully: + fanctl.run() + fanctl.log_debug("Stop daemon main loop") + + sys.exit(0) + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/pid_config_questone2.ini b/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/pid_config_questone2.ini new file mode 100644 index 0000000000..7227dd6273 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/pid_config_questone2.ini @@ -0,0 +1,19 @@ +#[PID thermal control setting] +[PID enable] +PID_enable=0 + +[SWITCH_TEMP] +setpoint = 95 +P = 3 +I = 0.5 +D = 0.5 +min_output = 76 + +[CPU_TEMP] +setpoint = -15 +P = 3 +I = 0.5 +D = 0.5 +min_output = 76 + + diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/questone2-modprobe.conf b/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/questone2-modprobe.conf new file mode 100644 index 0000000000..57a28ea72e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/questone2-modprobe.conf @@ -0,0 +1 @@ +options switchboard_fpga allow_unsafe_i2c_access=1 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/questone2-modules.conf b/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/questone2-modules.conf new file mode 100644 index 0000000000..574c48f7a6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/cfg/questone2-modules.conf @@ -0,0 +1,16 @@ +# /etc/modules: kernel modules to load at boot time. +# +# This file contains the names of kernel modules that should be loaded +# at boot time, one per line. Lines beginning with "#" are ignored. + +i2c-i801 +i2c-isch +i2c-ismt +i2c-dev +i2c-mux +i2c-smbus + +i2c-mux-gpio +i2c-mux-pca954x +8021q + diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/Makefile new file mode 100644 index 0000000000..23f793dc3e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/Makefile @@ -0,0 +1 @@ +obj-m := mc24lc64t.o questone2_switchboard.o questone2_baseboard_cpld.o sff_8436_eeprom.o optoe.o diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/mc24lc64t.c new file mode 100644 index 0000000000..ae79770a4d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/mc24lc64t.c @@ -0,0 +1,173 @@ +/* + * mc24lc64t.c - driver for Microchip 24LC64T + * + * Copyright (C) 2017 Celestica Corp. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define EEPROM_SIZE 8192 //mc24lt64t eeprom size in bytes. + +struct mc24lc64t_data { + struct mutex update_lock; +}; + +static ssize_t mc24lc64t_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, read_time, i = 0; + int status; + + mutex_lock(&drvdata->update_lock); + + if (i2c_smbus_write_byte_data(client, off>>8, off)) + { + status = -EIO; + goto exit; + } + + msleep(1); + +begin: + + if (i < count) + { + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + do { + read_time = jiffies; + + status = i2c_smbus_read_byte(client); + if (status >= 0) + { + buf[i++] = status; + goto begin; + } + } while (time_before(read_time, timeout)); + + status = -ETIMEDOUT; + goto exit; + } + + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + + return status; +} + +static ssize_t mc24lc64t_write (struct file *filp, struct kobject *kobj, + struct bin_attribute *bin_attr, + char *buf, loff_t off, size_t count){ + + struct i2c_client *client = kobj_to_i2c_client(kobj); + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + unsigned long timeout, write_time, i = 0; + int status; + u16 value; + + mutex_lock(&drvdata->update_lock); + +begin: + if (i < count){ + timeout = jiffies + msecs_to_jiffies(25); /* 25 mS timeout*/ + value = (buf[i] << 8)| off; + do { + write_time = jiffies; + status = i2c_smbus_write_word_data(client, off>>8, value); + if (status >= 0) + { + // increase offset + off++; + // increase buffer index + i++; + goto begin; + } + } while (time_before(write_time, timeout)); + status = -ETIMEDOUT; + goto exit; + } + status = count; + +exit: + mutex_unlock(&drvdata->update_lock); + return status; +} + +static struct bin_attribute mc24lc64t_bit_attr = { + .attr = { + .name = "eeprom", + .mode = S_IRUGO | S_IWUGO, + }, + .size = EEPROM_SIZE, + .read = mc24lc64t_read, + .write = mc24lc64t_write, +}; + +static int mc24lc64t_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adapter = client->adapter; + struct mc24lc64t_data *drvdata; + int err; + + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE_DATA + | I2C_FUNC_SMBUS_READ_BYTE)) + return -EPFNOSUPPORT; + + if (!(drvdata = devm_kzalloc(&client->dev, + sizeof(struct mc24lc64t_data), GFP_KERNEL))) + return -ENOMEM; + + i2c_set_clientdata(client, drvdata); + mutex_init(&drvdata->update_lock); + + err = sysfs_create_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return err; +} + +static int mc24lc64t_remove(struct i2c_client *client) +{ + struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); + + return 0; +} + +static const struct i2c_device_id mc24lc64t_id[] = { + { "24lc64t", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mc24lc64t_id); + +static struct i2c_driver mc24lc64t_driver = { + .driver = { + .name = "mc24lc64t", + .owner = THIS_MODULE, + }, + .probe = mc24lc64t_probe, + .remove = mc24lc64t_remove, + .id_table = mc24lc64t_id, +}; + +module_i2c_driver(mc24lc64t_driver); + +MODULE_AUTHOR("Abhisit Sangjan "); +MODULE_DESCRIPTION("Microchip 24LC64T Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/optoe.c b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/optoe.c new file mode 100644 index 0000000000..a16bdfc96a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/optoe.c @@ -0,0 +1,1147 @@ +/* + * optoe.c - A driver to read and write the EEPROM on optical transceivers + * (SFP, QSFP and similar I2C based devices) + * + * Copyright (C) 2014 Cumulus networks Inc. + * Copyright (C) 2017 Finisar Corp. + * + * 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 + * the Freeoftware Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +/* + * Description: + * a) Optical transceiver EEPROM read/write transactions are just like + * the at24 eeproms managed by the at24.c i2c driver + * b) The register/memory layout is up to 256 128 byte pages defined by + * a "pages valid" register and switched via a "page select" + * register as explained in below diagram. + * c) 256 bytes are mapped at a time. 'Lower page 00h' is the first 128 + * bytes of address space, and always references the same + * location, independent of the page select register. + * All mapped pages are mapped into the upper 128 bytes + * (offset 128-255) of the i2c address. + * d) Devices with one I2C address (eg QSFP) use I2C address 0x50 + * (A0h in the spec), and map all pages in the upper 128 bytes + * of that address. + * e) Devices with two I2C addresses (eg SFP) have 256 bytes of data + * at I2C address 0x50, and 256 bytes of data at I2C address + * 0x51 (A2h in the spec). Page selection and paged access + * only apply to this second I2C address (0x51). + * e) The address space is presented, by the driver, as a linear + * address space. For devices with one I2C client at address + * 0x50 (eg QSFP), offset 0-127 are in the lower + * half of address 50/A0h/client[0]. Offset 128-255 are in + * page 0, 256-383 are page 1, etc. More generally, offset + * 'n' resides in page (n/128)-1. ('page -1' is the lower + * half, offset 0-127). + * f) For devices with two I2C clients at address 0x50 and 0x51 (eg SFP), + * the address space places offset 0-127 in the lower + * half of 50/A0/client[0], offset 128-255 in the upper + * half. Offset 256-383 is in the lower half of 51/A2/client[1]. + * Offset 384-511 is in page 0, in the upper half of 51/A2/... + * Offset 512-639 is in page 1, in the upper half of 51/A2/... + * Offset 'n' is in page (n/128)-3 (for n > 383) + * + * One I2c addressed (eg QSFP) Memory Map + * + * 2-Wire Serial Address: 1010000x + * + * Lower Page 00h (128 bytes) + * ===================== + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * |Page Select Byte(127)| + * ===================== + * | + * | + * | + * | + * V + * ------------------------------------------------------------ + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * V V V V + * ------------ -------------- --------------- -------------- + * | | | | | | | | + * | Upper | | Upper | | Upper | | Upper | + * | Page 00h | | Page 01h | | Page 02h | | Page 03h | + * | | | (Optional) | | (Optional) | | (Optional | + * | | | | | | | for Cable | + * | | | | | | | Assemblies) | + * | ID | | AST | | User | | | + * | Fields | | Table | | EEPROM Data | | | + * | | | | | | | | + * | | | | | | | | + * | | | | | | | | + * ------------ -------------- --------------- -------------- + * + * The SFF 8436 (QSFP) spec only defines the 4 pages described above. + * In anticipation of future applications and devices, this driver + * supports access to the full architected range, 256 pages. + * + **/ + +/* #define DEBUG 1 */ + +#undef EEPROM_CLASS +#ifdef CONFIG_EEPROM_CLASS +#define EEPROM_CLASS +#endif +#ifdef CONFIG_EEPROM_CLASS_MODULE +#define EEPROM_CLASS +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef EEPROM_CLASS +#include +#endif + +#include + +/* The maximum length of a port name */ +#define MAX_PORT_NAME_LEN 20 + +struct optoe_platform_data { + u32 byte_len; /* size (sum of all addr) */ + u16 page_size; /* for writes */ + u8 flags; + void *dummy1; /* backward compatibility */ + void *dummy2; /* backward compatibility */ + +#ifdef EEPROM_CLASS + struct eeprom_platform_data *eeprom_data; +#endif + char port_name[MAX_PORT_NAME_LEN]; +}; + +/* fundamental unit of addressing for EEPROM */ +#define OPTOE_PAGE_SIZE 128 +/* + * Single address devices (eg QSFP) have 256 pages, plus the unpaged + * low 128 bytes. If the device does not support paging, it is + * only 2 'pages' long. + */ +#define OPTOE_ARCH_PAGES 256 +#define ONE_ADDR_EEPROM_SIZE ((1 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) +#define ONE_ADDR_EEPROM_UNPAGED_SIZE (2 * OPTOE_PAGE_SIZE) +/* + * Dual address devices (eg SFP) have 256 pages, plus the unpaged + * low 128 bytes, plus 256 bytes at 0x50. If the device does not + * support paging, it is 4 'pages' long. + */ +#define TWO_ADDR_EEPROM_SIZE ((3 + OPTOE_ARCH_PAGES) * OPTOE_PAGE_SIZE) +#define TWO_ADDR_EEPROM_UNPAGED_SIZE (4 * OPTOE_PAGE_SIZE) +#define TWO_ADDR_NO_0X51_SIZE (2 * OPTOE_PAGE_SIZE) + +/* a few constants to find our way around the EEPROM */ +#define OPTOE_PAGE_SELECT_REG 0x7F +#define ONE_ADDR_PAGEABLE_REG 0x02 +#define ONE_ADDR_NOT_PAGEABLE (1<<2) +#define TWO_ADDR_PAGEABLE_REG 0x40 +#define TWO_ADDR_PAGEABLE (1<<4) +#define TWO_ADDR_0X51_REG 92 +#define TWO_ADDR_0X51_SUPP (1<<6) +#define OPTOE_ID_REG 0 +#define OPTOE_READ_OP 0 +#define OPTOE_WRITE_OP 1 +#define OPTOE_EOF 0 /* used for access beyond end of device */ + +struct optoe_data { + struct optoe_platform_data chip; + int use_smbus; + char port_name[MAX_PORT_NAME_LEN]; + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + struct bin_attribute bin; + struct attribute_group attr_group; + + u8 *writebuf; + unsigned int write_max; + + unsigned int num_addresses; + +#ifdef EEPROM_CLASS + struct eeprom_device *eeprom_dev; +#endif + + /* dev_class: ONE_ADDR (QSFP) or TWO_ADDR (SFP) */ + int dev_class; + + struct i2c_client *client[]; +}; + + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned int io_limit = OPTOE_PAGE_SIZE; + +/* + * specs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned int write_timeout = 25; + +/* + * flags to distinguish one-address (QSFP family) from two-address (SFP family) + * If the family is not known, figure it out when the device is accessed + */ +#define ONE_ADDR 1 +#define TWO_ADDR 2 + +static const struct i2c_device_id optoe_ids[] = { + { "optoe1", ONE_ADDR }, + { "optoe2", TWO_ADDR }, + { "sff8436", ONE_ADDR }, + { "24c04", TWO_ADDR }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, optoe_ids); + +/*-------------------------------------------------------------------------*/ +/* + * This routine computes the addressing information to be used for + * a given r/w request. + * + * Task is to calculate the client (0 = i2c addr 50, 1 = i2c addr 51), + * the page, and the offset. + * + * Handles both single address (eg QSFP) and two address (eg SFP). + * For SFP, offset 0-255 are on client[0], >255 is on client[1] + * Offset 256-383 are on the lower half of client[1] + * Pages are accessible on the upper half of client[1]. + * Offset >383 are in 128 byte pages mapped into the upper half + * + * For QSFP, all offsets are on client[0] + * offset 0-127 are on the lower half of client[0] (no paging) + * Pages are accessible on the upper half of client[1]. + * Offset >127 are in 128 byte pages mapped into the upper half + * + * Callers must not read/write beyond the end of a client or a page + * without recomputing the client/page. Hence offset (within page) + * plus length must be less than or equal to 128. (Note that this + * routine does not have access to the length of the call, hence + * cannot do the validity check.) + * + * Offset within Lower Page 00h and Upper Page 00h are not recomputed + */ + +static uint8_t optoe_translate_offset(struct optoe_data *optoe, + loff_t *offset, struct i2c_client **client) +{ + unsigned int page = 0; + + *client = optoe->client[0]; + + /* if SFP style, offset > 255, shift to i2c addr 0x51 */ + if (optoe->dev_class == TWO_ADDR) { + if (*offset > 255) { + /* like QSFP, but shifted to client[1] */ + *client = optoe->client[1]; + *offset -= 256; + } + } + + /* + * if offset is in the range 0-128... + * page doesn't matter (using lower half), return 0. + * offset is already correct (don't add 128 to get to paged area) + */ + if (*offset < OPTOE_PAGE_SIZE) + return page; + + /* note, page will always be positive since *offset >= 128 */ + page = (*offset >> 7)-1; + /* 0x80 places the offset in the top half, offset is last 7 bits */ + *offset = OPTOE_PAGE_SIZE + (*offset & 0x7f); + + return page; /* note also returning client and offset */ +} + +static ssize_t optoe_eeprom_read(struct optoe_data *optoe, + struct i2c_client *client, + char *buf, unsigned int offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + unsigned long timeout, read_time; + int status, i; + + memset(msg, 0, sizeof(msg)); + + switch (optoe->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* + * When we have a better choice than SMBus calls, use a + * combined I2C message. Write address; then read up to + * io_limit data bytes. msgbuf is u8 and will cast to our + * needs. + */ + i = 0; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + + switch (optoe->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_read_i2c_block_data(client, offset, + count, buf); + break; + case I2C_SMBUS_WORD_DATA: + status = i2c_smbus_read_word_data(client, offset); + if (status >= 0) { + buf[0] = status & 0xff; + if (count == 2) + buf[1] = status >> 8; + status = count; + } + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_read_byte_data(client, offset); + if (status >= 0) { + buf[0] = status; + status = count; + } + break; + default: + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + status = count; + } + + dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) /* happy path */ + return count; + + if (status == -ENXIO) /* no module present */ + return status; + + /* REVISIT: at HZ=100, this is sloooow */ + usleep_range(1000, 2000); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t optoe_eeprom_write(struct optoe_data *optoe, + struct i2c_client *client, + const char *buf, + unsigned int offset, size_t count) +{ + struct i2c_msg msg; + ssize_t status; + unsigned long timeout, write_time; + unsigned int next_page_start; + int i = 0; + + /* write max is at most a page + * (In this driver, write_max is actually one byte!) + */ + if (count > optoe->write_max) + count = optoe->write_max; + + /* shorten count if necessary to avoid crossing page boundary */ + next_page_start = roundup(offset + 1, OPTOE_PAGE_SIZE); + if (offset + count > next_page_start) + count = next_page_start - offset; + + switch (optoe->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* If we'll use I2C calls for I/O, set up the message */ + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = optoe->writebuf; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + break; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + + switch (optoe->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + break; + case I2C_SMBUS_WORD_DATA: + if (count == 2) { + status = i2c_smbus_write_word_data(client, + offset, (u16)((buf[0])|(buf[1] << 8))); + } else { + /* count = 1 */ + status = i2c_smbus_write_byte_data(client, + offset, buf[0]); + } + if (status == 0) + status = count; + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_write_byte_data(client, offset, + buf[0]); + if (status == 0) + status = count; + break; + default: + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + break; + } + + dev_dbg(&client->dev, "eeprom write %zu@%d --> %ld (%lu)\n", + count, offset, (long int) status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + usleep_range(1000, 2000); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + + +static ssize_t optoe_eeprom_update_client(struct optoe_data *optoe, + char *buf, loff_t off, + size_t count, int opcode) +{ + struct i2c_client *client; + ssize_t retval = 0; + uint8_t page = 0; + loff_t phy_offset = off; + int ret = 0; + + page = optoe_translate_offset(optoe, &phy_offset, &client); + dev_dbg(&client->dev, + "%s off %lld page:%d phy_offset:%lld, count:%ld, opcode:%d\n", + __func__, off, page, phy_offset, (long int) count, opcode); + if (page > 0) { + ret = optoe_eeprom_write(optoe, client, &page, + OPTOE_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_dbg(&client->dev, + "Write page register for page %d failed ret:%d!\n", + page, ret); + return ret; + } + } + + while (count) { + ssize_t status; + + if (opcode == OPTOE_READ_OP) { + status = optoe_eeprom_read(optoe, client, + buf, phy_offset, count); + } else { + status = optoe_eeprom_write(optoe, client, + buf, phy_offset, count); + } + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + buf += status; + phy_offset += status; + count -= status; + retval += status; + } + + + if (page > 0) { + /* return the page register to page 0 (why?) */ + page = 0; + ret = optoe_eeprom_write(optoe, client, &page, + OPTOE_PAGE_SELECT_REG, 1); + if (ret < 0) { + dev_err(&client->dev, + "Restore page register to 0 failed:%d!\n", ret); + /* error only if nothing has been transferred */ + if (retval == 0) + retval = ret; + } + } + return retval; +} + +/* + * Figure out if this access is within the range of supported pages. + * Note this is called on every access because we don't know if the + * module has been replaced since the last call. + * If/when modules support more pages, this is the routine to update + * to validate and allow access to additional pages. + * + * Returns updated len for this access: + * - entire access is legal, original len is returned. + * - access begins legal but is too long, len is truncated to fit. + * - initial offset exceeds supported pages, return OPTOE_EOF (zero) + */ +static ssize_t optoe_page_legal(struct optoe_data *optoe, + loff_t off, size_t len) +{ + struct i2c_client *client = optoe->client[0]; + u8 regval; + int status; + size_t maxlen; + + if (off < 0) + return -EINVAL; + if (optoe->dev_class == TWO_ADDR) { + /* SFP case */ + /* if only using addr 0x50 (first 256 bytes) we're good */ + if ((off + len) <= TWO_ADDR_NO_0X51_SIZE) + return len; + /* if offset exceeds possible pages, we're not good */ + if (off >= TWO_ADDR_EEPROM_SIZE) + return OPTOE_EOF; + /* in between, are pages supported? */ + status = optoe_eeprom_read(optoe, client, ®val, + TWO_ADDR_PAGEABLE_REG, 1); + if (status < 0) + return status; /* error out (no module?) */ + if (regval & TWO_ADDR_PAGEABLE) { + /* Pages supported, trim len to the end of pages */ + maxlen = TWO_ADDR_EEPROM_SIZE - off; + } else { + /* pages not supported, trim len to unpaged size */ + if (off >= TWO_ADDR_EEPROM_UNPAGED_SIZE) + return OPTOE_EOF; + + /* will be accessing addr 0x51, is that supported? */ + /* byte 92, bit 6 implies DDM support, 0x51 support */ + status = optoe_eeprom_read(optoe, client, ®val, + TWO_ADDR_0X51_REG, 1); + if (status < 0) + return status; + if (regval & TWO_ADDR_0X51_SUPP) { + /* addr 0x51 is OK */ + maxlen = TWO_ADDR_EEPROM_UNPAGED_SIZE - off; + } else { + /* addr 0x51 NOT supported, trim to 256 max */ + if (off >= TWO_ADDR_NO_0X51_SIZE) + return OPTOE_EOF; + maxlen = TWO_ADDR_NO_0X51_SIZE - off; + } + } + len = (len > maxlen) ? maxlen : len; + dev_dbg(&client->dev, + "page_legal, SFP, off %lld len %ld\n", + off, (long int) len); + } else { + /* QSFP case */ + /* if no pages needed, we're good */ + if ((off + len) <= ONE_ADDR_EEPROM_UNPAGED_SIZE) + return len; + /* if offset exceeds possible pages, we're not good */ + if (off >= ONE_ADDR_EEPROM_SIZE) + return OPTOE_EOF; + /* in between, are pages supported? */ + status = optoe_eeprom_read(optoe, client, ®val, + ONE_ADDR_PAGEABLE_REG, 1); + if (status < 0) + return status; /* error out (no module?) */ + if (regval & ONE_ADDR_NOT_PAGEABLE) { + /* pages not supported, trim len to unpaged size */ + if (off >= ONE_ADDR_EEPROM_UNPAGED_SIZE) + return OPTOE_EOF; + maxlen = ONE_ADDR_EEPROM_UNPAGED_SIZE - off; + } else { + /* Pages supported, trim len to the end of pages */ + maxlen = ONE_ADDR_EEPROM_SIZE - off; + } + len = (len > maxlen) ? maxlen : len; + dev_dbg(&client->dev, + "page_legal, QSFP, off %lld len %ld\n", + off, (long int) len); + } + return len; +} + +static ssize_t optoe_read_write(struct optoe_data *optoe, + char *buf, loff_t off, size_t len, int opcode) +{ + struct i2c_client *client = optoe->client[0]; + int chunk; + int status = 0; + ssize_t retval; + size_t pending_len = 0, chunk_len = 0; + loff_t chunk_offset = 0, chunk_start_offset = 0; + loff_t chunk_end_offset = 0; + + dev_dbg(&client->dev, + "%s: off %lld len:%ld, opcode:%s\n", + __func__, off, (long int) len, + (opcode == OPTOE_READ_OP) ? "r" : "w"); + if (unlikely(!len)) + return len; + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&optoe->lock); + + /* + * Confirm this access fits within the device suppored addr range + */ + status = optoe_page_legal(optoe, off, len); + if ((status == OPTOE_EOF) || (status < 0)) { + mutex_unlock(&optoe->lock); + return status; + } + len = status; + + /* + * For each (128 byte) chunk involved in this request, issue a + * separate call to sff_eeprom_update_client(), to + * ensure that each access recalculates the client/page + * and writes the page register as needed. + * Note that chunk to page mapping is confusing, is different for + * QSFP and SFP, and never needs to be done. Don't try! + */ + pending_len = len; /* amount remaining to transfer */ + retval = 0; /* amount transferred */ + for (chunk = off >> 7; chunk <= (off + len - 1) >> 7; chunk++) { + + /* + * Compute the offset and number of bytes to be read/write + * + * 1. start at an offset not equal to 0 (within the chunk) + * and read/write less than the rest of the chunk + * 2. start at an offset not equal to 0 and read/write the rest + * of the chunk + * 3. start at offset 0 (within the chunk) and read/write less + * than entire chunk + * 4. start at offset 0 (within the chunk), and read/write + * the entire chunk + */ + chunk_start_offset = chunk * OPTOE_PAGE_SIZE; + chunk_end_offset = chunk_start_offset + OPTOE_PAGE_SIZE; + + if (chunk_start_offset < off) { + chunk_offset = off; + if ((off + pending_len) < chunk_end_offset) + chunk_len = pending_len; + else + chunk_len = chunk_end_offset - off; + } else { + chunk_offset = chunk_start_offset; + if (pending_len < OPTOE_PAGE_SIZE) + chunk_len = pending_len; + else + chunk_len = OPTOE_PAGE_SIZE; + } + + dev_dbg(&client->dev, + "sff_r/w: off %lld, len %ld, chunk_start_offset %lld, chunk_offset %lld, chunk_len %ld, pending_len %ld\n", + off, (long int) len, chunk_start_offset, chunk_offset, + (long int) chunk_len, (long int) pending_len); + + /* + * note: chunk_offset is from the start of the EEPROM, + * not the start of the chunk + */ + status = optoe_eeprom_update_client(optoe, buf, + chunk_offset, chunk_len, opcode); + if (status != chunk_len) { + /* This is another 'no device present' path */ + dev_dbg(&client->dev, + "o_u_c: chunk %d c_offset %lld c_len %ld failed %d!\n", + chunk, chunk_offset, (long int) chunk_len, status); + if (status > 0) + retval += status; + if (retval == 0) + retval = status; + break; + } + buf += status; + pending_len -= status; + retval += status; + } + mutex_unlock(&optoe->lock); + + return retval; +} + +static ssize_t optoe_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, + struct device, kobj)); + struct optoe_data *optoe = i2c_get_clientdata(client); + + return optoe_read_write(optoe, buf, off, count, OPTOE_READ_OP); +} + + +static ssize_t optoe_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, + struct device, kobj)); + struct optoe_data *optoe = i2c_get_clientdata(client); + + return optoe_read_write(optoe, buf, off, count, OPTOE_WRITE_OP); +} + +static int optoe_remove(struct i2c_client *client) +{ + struct optoe_data *optoe; + int i; + + optoe = i2c_get_clientdata(client); + sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); + sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); + + for (i = 1; i < optoe->num_addresses; i++) + i2c_unregister_device(optoe->client[i]); + +#ifdef EEPROM_CLASS + eeprom_device_unregister(optoe->eeprom_dev); +#endif + + kfree(optoe->writebuf); + kfree(optoe); + return 0; +} + +static ssize_t show_dev_class(struct device *dev, + struct device_attribute *dattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct optoe_data *optoe = i2c_get_clientdata(client); + ssize_t count; + + mutex_lock(&optoe->lock); + count = sprintf(buf, "%d\n", optoe->dev_class); + mutex_unlock(&optoe->lock); + + return count; +} + +static ssize_t set_dev_class(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct optoe_data *optoe = i2c_get_clientdata(client); + int dev_class; + + /* + * dev_class is actually the number of i2c addresses used, thus + * legal values are "1" (QSFP class) and "2" (SFP class) + */ + + if (kstrtoint(buf, 0, &dev_class) != 0 || + dev_class < 1 || dev_class > 2) + return -EINVAL; + + mutex_lock(&optoe->lock); + optoe->dev_class = dev_class; + mutex_unlock(&optoe->lock); + + return count; +} + +/* + * if using the EEPROM CLASS driver, we don't report a port_name, + * the EEPROM CLASS drive handles that. Hence all this code is + * only compiled if we are NOT using the EEPROM CLASS driver. + */ +#ifndef EEPROM_CLASS + +static ssize_t show_port_name(struct device *dev, + struct device_attribute *dattr, char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct optoe_data *optoe = i2c_get_clientdata(client); + ssize_t count; + + mutex_lock(&optoe->lock); + count = sprintf(buf, "%s\n", optoe->port_name); + mutex_unlock(&optoe->lock); + + return count; +} + +static ssize_t set_port_name(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct optoe_data *optoe = i2c_get_clientdata(client); + char port_name[MAX_PORT_NAME_LEN]; + + /* no checking, this value is not used except by show_port_name */ + + if (sscanf(buf, "%19s", port_name) != 1) + return -EINVAL; + + mutex_lock(&optoe->lock); + strcpy(optoe->port_name, port_name); + mutex_unlock(&optoe->lock); + + return count; +} + +static DEVICE_ATTR(port_name, 0644, show_port_name, set_port_name); +#endif /* if NOT defined EEPROM_CLASS, the common case */ + +static DEVICE_ATTR(dev_class, 0644, show_dev_class, set_dev_class); + +static struct attribute *optoe_attrs[] = { +#ifndef EEPROM_CLASS + &dev_attr_port_name.attr, +#endif + &dev_attr_dev_class.attr, + NULL, +}; + +static struct attribute_group optoe_attr_group = { + .attrs = optoe_attrs, +}; + +static int optoe_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err; + int use_smbus = 0; + struct optoe_platform_data chip; + struct optoe_data *optoe; + int num_addresses = 0; + char port_name[MAX_PORT_NAME_LEN]; + + if (client->addr != 0x50) { + dev_dbg(&client->dev, "probe, bad i2c addr: 0x%x\n", + client->addr); + err = -EINVAL; + goto exit; + } + + if (client->dev.platform_data) { + chip = *(struct optoe_platform_data *)client->dev.platform_data; + /* take the port name from the supplied platform data */ +#ifdef EEPROM_CLASS + strncpy(port_name, chip.eeprom_data->label, MAX_PORT_NAME_LEN); +#else + memcpy(port_name, chip.port_name, MAX_PORT_NAME_LEN); +#endif + dev_dbg(&client->dev, + "probe, chip provided, flags:0x%x; name: %s\n", + chip.flags, client->name); + } else { + if (!id->driver_data) { + err = -ENODEV; + goto exit; + } + dev_dbg(&client->dev, "probe, building chip\n"); + strcpy(port_name, "unitialized"); + chip.flags = 0; +#ifdef EEPROM_CLASS + chip.eeprom_data = NULL; +#endif + } + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + err = -EPFNOSUPPORT; + goto exit; + } + } + + + /* + * Make room for two i2c clients + */ + num_addresses = 2; + + optoe = kzalloc(sizeof(struct optoe_data) + + num_addresses * sizeof(struct i2c_client *), + GFP_KERNEL); + if (!optoe) { + err = -ENOMEM; + goto exit; + } + + mutex_init(&optoe->lock); + + /* determine whether this is a one-address or two-address module */ + if ((strcmp(client->name, "optoe1") == 0) || + (strcmp(client->name, "sff8436") == 0)) { + /* one-address (eg QSFP) family */ + optoe->dev_class = ONE_ADDR; + chip.byte_len = ONE_ADDR_EEPROM_SIZE; + num_addresses = 1; + } else if ((strcmp(client->name, "optoe2") == 0) || + (strcmp(client->name, "24c04") == 0)) { + /* SFP family */ + optoe->dev_class = TWO_ADDR; + chip.byte_len = TWO_ADDR_EEPROM_SIZE; + } else { /* those were the only two choices */ + err = -EINVAL; + goto exit; + } + + dev_dbg(&client->dev, "dev_class: %d\n", optoe->dev_class); + optoe->use_smbus = use_smbus; + optoe->chip = chip; + optoe->num_addresses = num_addresses; + memcpy(optoe->port_name, port_name, MAX_PORT_NAME_LEN); + + /* + * Export the EEPROM bytes through sysfs, since that's convenient. + * By default, only root should see the data (maybe passwords etc) + */ + sysfs_bin_attr_init(&optoe->bin); + optoe->bin.attr.name = "eeprom"; + optoe->bin.attr.mode = 0444; + optoe->bin.read = optoe_bin_read; + optoe->bin.size = chip.byte_len; + + if (!use_smbus || + (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_WORD_DATA) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + /* + * NOTE: AN-2079 + * Finisar recommends that the host implement 1 byte writes + * only since this module only supports 32 byte page boundaries. + * 2 byte writes are acceptable for PE and Vout changes per + * Application Note AN-2071. + */ + unsigned int write_max = 1; + + optoe->bin.write = optoe_bin_write; + optoe->bin.attr.mode |= 0200; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + optoe->write_max = write_max; + + /* buffer (data + address at the beginning) */ + optoe->writebuf = kmalloc(write_max + 2, GFP_KERNEL); + if (!optoe->writebuf) { + err = -ENOMEM; + goto exit_kfree; + } + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + + optoe->client[0] = client; + + /* SFF-8472 spec requires that the second I2C address be 0x51 */ + if (num_addresses == 2) { + optoe->client[1] = i2c_new_dummy_device(client->adapter, 0x51); + if (!optoe->client[1]) { + dev_err(&client->dev, "address 0x51 unavailable\n"); + err = -EADDRINUSE; + goto err_struct; + } + } + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &optoe->bin); + if (err) + goto err_struct; + + optoe->attr_group = optoe_attr_group; + + err = sysfs_create_group(&client->dev.kobj, &optoe->attr_group); + if (err) { + dev_err(&client->dev, "failed to create sysfs attribute group.\n"); + goto err_struct; + } + +#ifdef EEPROM_CLASS + optoe->eeprom_dev = eeprom_device_register(&client->dev, + chip.eeprom_data); + if (IS_ERR(optoe->eeprom_dev)) { + dev_err(&client->dev, "error registering eeprom device.\n"); + err = PTR_ERR(optoe->eeprom_dev); + goto err_sysfs_cleanup; + } +#endif + + i2c_set_clientdata(client, optoe); + + dev_info(&client->dev, "%zu byte %s EEPROM, %s\n", + optoe->bin.size, client->name, + optoe->bin.write ? "read/write" : "read-only"); + + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, + "Falling back to %s reads, performance will suffer\n", + use_smbus == I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + return 0; + +#ifdef EEPROM_CLASS +err_sysfs_cleanup: + sysfs_remove_group(&client->dev.kobj, &optoe->attr_group); + sysfs_remove_bin_file(&client->dev.kobj, &optoe->bin); +#endif + +err_struct: + if (num_addresses == 2) { + if (optoe->client[1]) + i2c_unregister_device(optoe->client[1]); + } + + kfree(optoe->writebuf); +exit_kfree: + kfree(optoe); +exit: + dev_dbg(&client->dev, "probe error %d\n", err); + + return err; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver optoe_driver = { + .driver = { + .name = "optoe", + .owner = THIS_MODULE, + }, + .probe = optoe_probe, + .remove = optoe_remove, + .id_table = optoe_ids, +}; + +static int __init optoe_init(void) +{ + + if (!io_limit) { + pr_err("optoe: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&optoe_driver); +} +module_init(optoe_init); + +static void __exit optoe_exit(void) +{ + i2c_del_driver(&optoe_driver); +} +module_exit(optoe_exit); + +MODULE_DESCRIPTION("Driver for optical transceiver (SFP, QSFP, ...) EEPROMs"); +MODULE_AUTHOR("DON BOLLINGER "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/questone2_baseboard_cpld.c b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/questone2_baseboard_cpld.c new file mode 100644 index 0000000000..1a5527f0d6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/questone2_baseboard_cpld.c @@ -0,0 +1,409 @@ +/* + * seastone2_baseboard_cpld.c - driver for Seastone2 Base Board CPLD + * This driver implement sysfs for CPLD register access using LPC bus. + * Copyright (C) 2017 Celestica Corp. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "sys_cpld" +/** + * CPLD register address for read and write. + */ +#define VERSION_ADDR 0xA100 +#define SCRATCH_ADDR 0xA101 +#define SYS_LED_ADDR 0xA162 +#define THERMAL_ADDR 0xA176 +#define CPLD_REGISTER_SIZE 0x77 + +struct baseboard_cpld_data { + struct mutex cpld_lock; + uint16_t read_addr; +}; + +struct baseboard_cpld_data *cpld_data; + +/** + * Read the value from scratch register as hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t scratch_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return sprintf(buf,"0x%2.2x\n", data); +} + +/** + * Set scratch register with specific hex string. + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t scratch_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned long data; + char *last; + + mutex_lock(&cpld_data->cpld_lock); + data = (uint16_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + mutex_unlock(&cpld_data->cpld_lock); + return -EINVAL; + } + outb(data, SCRATCH_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(scratch); + + +/* CPLD version attributes */ +static ssize_t version_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + int len = sprintf(buf, "0x%2.2x\n",inb(VERSION_ADDR)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RO(version); + + +static ssize_t getreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // CPLD register is one byte + 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) +{ + // CPLD register is one byte + mutex_lock(&cpld_data->cpld_lock); + int len = sprintf(buf, "0x%2.2x\n",inb(cpld_data->read_addr)); + mutex_unlock(&cpld_data->cpld_lock); + return len; +} +static DEVICE_ATTR_RW(getreg); + +static ssize_t setreg_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + // CPLD register is one byte + 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 DEVICE_ATTR_WO(setreg); + +/** + * Read all CPLD register in binary mode. + * @return number of byte read. + */ +static ssize_t dump_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + unsigned long i=0; + ssize_t status; + + mutex_lock(&cpld_data->cpld_lock); +begin: + if(i < count){ + buf[i++] = inb(VERSION_ADDR + off); + off++; + msleep(1); + goto begin; + } + status = count; +exit: + mutex_unlock(&cpld_data->cpld_lock); + return status; +} +static BIN_ATTR_RO(dump, CPLD_REGISTER_SIZE); + +/** + * Show system led status - on/off/1k/4k + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t sys_led_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = data & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "4k" : data ==0x01 ? "1k": "on"); +} + +/** + * Set the status of system led - on/off/1k/4k + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t sys_led_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "4k")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "1k")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "on")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~(0x3); + data = data | led_status; + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led); + +/** + * Show system led color - both/green/yellow/none + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer for get value + * @return Hex string read from scratch register. + */ +static ssize_t sys_led_color_show(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + unsigned char data = 0; + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + data = (data >> 4) & 0x3; + return sprintf(buf, "%s\n", + data == 0x03 ? "off" : data == 0x02 ? "yellow" : data ==0x01 ? "green": "both"); +} + +/** + * Set the color of system led - both/green/yellow/none + * @param dev kernel device + * @param devattr kernel device attribute + * @param buf buffer of set value + * @param count number of bytes in buffer + * @return number of bytes written, or error code < 0. + */ +static ssize_t sys_led_color_store(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + unsigned char led_status,data; + if(sysfs_streq(buf, "off")){ + led_status = 0x03; + }else if(sysfs_streq(buf, "yellow")){ + led_status = 0x02; + }else if(sysfs_streq(buf, "green")){ + led_status = 0x01; + }else if(sysfs_streq(buf, "both")){ + led_status = 0x00; + }else{ + count = -EINVAL; + return count; + } + mutex_lock(&cpld_data->cpld_lock); + data = inb(SYS_LED_ADDR); + data = data & ~( 0x3 << 4); + data = data | (led_status << 4); + outb(data, SYS_LED_ADDR); + mutex_unlock(&cpld_data->cpld_lock); + return count; +} +static DEVICE_ATTR_RW(sys_led_color); + +static struct attribute *baseboard_cpld_attrs[] = { + &dev_attr_version.attr, + &dev_attr_scratch.attr, + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + &dev_attr_sys_led.attr, + &dev_attr_sys_led_color.attr, + NULL, +}; + +static struct bin_attribute *baseboard_cpld_bin_attrs[] = { + &bin_attr_dump, + NULL, +}; + +static struct attribute_group baseboard_cpld_attrs_grp = { + .attrs = baseboard_cpld_attrs, + .bin_attrs = baseboard_cpld_bin_attrs, +}; + +static struct resource baseboard_cpld_resources[] = { + { + .start = 0xA100, + .end = 0xA1FF, + .flags = IORESOURCE_IO, + }, +}; + +static void baseboard_cpld_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device baseboard_cpld_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(baseboard_cpld_resources), + .resource = baseboard_cpld_resources, + .dev = { + .release = baseboard_cpld_dev_release, + } +}; + +static int baseboard_cpld_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret =0; + int portid_count; + + cpld_data = devm_kzalloc(&pdev->dev, sizeof(struct baseboard_cpld_data), + GFP_KERNEL); + if (!cpld_data) + return -ENOMEM; + + mutex_init(&cpld_data->cpld_lock); + + cpld_data->read_addr = VERSION_ADDR; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + return -1; + } + + ret = sysfs_create_group(&pdev->dev.kobj, &baseboard_cpld_attrs_grp); + if (ret) { + printk(KERN_ERR "Cannot create sysfs for baseboard CPLD\n"); + } + return 0; +} + +static int baseboard_cpld_drv_remove(struct platform_device *pdev) +{ + sysfs_remove_group(&pdev->dev.kobj, &baseboard_cpld_attrs_grp); + return 0; +} + +static struct platform_driver baseboard_cpld_drv = { + .probe = baseboard_cpld_drv_probe, + .remove = __exit_p(baseboard_cpld_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +int baseboard_cpld_init(void) +{ + // Register platform device and platform driver + platform_device_register(&baseboard_cpld_dev); + platform_driver_register(&baseboard_cpld_drv); + return 0; +} + +void baseboard_cpld_exit(void) +{ + // Unregister platform device and platform driver + platform_driver_unregister(&baseboard_cpld_drv); + platform_device_unregister(&baseboard_cpld_dev); +} + +module_init(baseboard_cpld_init); +module_exit(baseboard_cpld_exit); + +MODULE_AUTHOR("Pradchaya Phucharoen "); +MODULE_DESCRIPTION("Celestica Seastone2/Questone2 Baseboard CPLD Driver"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/questone2_switchboard.c b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/questone2_switchboard.c new file mode 100644 index 0000000000..0519858ea3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/questone2_switchboard.c @@ -0,0 +1,2211 @@ +/* + * seastone_switchboard.c - driver for seastone2/questone2 Switch board FPGA/CPLD. + * + * Author: Pradchaya Phucharoen + * + * Copyright (C) 2017 Celestica Corp. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * / + * \--sys + * \--devices + * \--platform + * \--seastone2 + * |--FPGA + * |--CPLD1 + * |--CPLD2 + * \--SFF + * |--QSFP[1..32] + * \--SFP[1..2] + * + */ + +#ifndef TEST_MODE +#define MOD_VERSION "2.0.0" +#else +#define MOD_VERSION "TEST" +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + + +static int majorNumber; +#ifdef SEASTONE2 +#define CLASS_NAME "seastone2_fpga" +#define DRIVER_NAME "seastone2" +#define FPGA_PCI_NAME "Seastone2_fpga_pci" +#else +#define CLASS_NAME "questone2_fpga" +#define DRIVER_NAME "questone2" +#define FPGA_PCI_NAME "questone2_fpga_pci" +#endif +#define DEVICE_NAME "fwupgrade" + + +static int smbus_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, + unsigned short flags, char rw, u8 cmd, + int size, union i2c_smbus_data *data); + +static int fpgafw_init(void); +static void fpgafw_exit(void); + + +/* +======================================== +FPGA PCIe BAR 0 Registers +======================================== +Misc Control 0x00000000 – 0x000000FF. +I2C_CH1 0x00000100 - 0x00000110 +I2C_CH2 0x00000200 - 0x00000210. +I2C_CH3 0x00000300 - 0x00000310. +I2C_CH4 0x00000400 - 0x00000410. +I2C_CH5 0x00000500 - 0x00000510. +I2C_CH6 0x00000600 - 0x00000610. +I2C_CH7 0x00000700 - 0x00000710. +I2C_CH8 0x00000800 - 0x00000810. +I2C_CH9 0x00000900 - 0x00000910. +I2C_CH10 0x00000A00 - 0x00000A10. +SPI Master 0x00001200 - 0x00001300. +PORT XCVR 0x00004000 - 0x00004FFF. +*/ + +/* MISC */ +#define FPGA_VERSION 0x0000 +#define FPGA_VERSION_MJ_MSK 0xff00 +#define FPGA_VERSION_MN_MSK 0x00ff +#define FPGA_SCRATCH 0x0004 +#define FPGA_BROAD_TYPE 0x0008 +#define FPGA_BROAD_REV_MSK 0x0038 +#define FPGA_BROAD_ID_MSK 0x0007 +#define FPGA_PLL_STATUS 0x0014 +#define BMC_I2C_SCRATCH 0x0020 +#define FPGA_SLAVE_CPLD_REST 0x0030 +#define FPGA_PERIPH_RESET_CTRL 0x0034 +#define FPGA_INT_STATUS 0x0040 +#define FPGA_INT_SRC_STATUS 0x0044 +#define FPGA_INT_FLAG 0x0048 +#define FPGA_INT_MASK 0x004c +#define FPGA_MISC_CTRL 0x0050 +#define FPGA_MISC_STATUS 0x0054 +#define FPGA_AVS_VID_STATUS 0x0068 +#define FPGA_FEATURE_CARD_GPIO 0x0070 +#define FPGA_PORT_XCVR_READY 0x000c + +/* I2C_MASTER BASE ADDR */ +#define I2C_MASTER_FREQ_1 0x0100 +#define I2C_MASTER_CTRL_1 0x0104 +#define I2C_MASTER_STATUS_1 0x0108 +#define I2C_MASTER_DATA_1 0x010c +#define I2C_MASTER_PORT_ID_1 0x0110 +#define I2C_MASTER_CH_1 1 +#define I2C_MASTER_CH_2 2 +#define I2C_MASTER_CH_3 3 +#define I2C_MASTER_CH_4 4 +#define I2C_MASTER_CH_5 5 +#define I2C_MASTER_CH_6 6 +#define I2C_MASTER_CH_7 7 +#define I2C_MASTER_CH_8 8 +#define I2C_MASTER_CH_9 9 +#define I2C_MASTER_CH_10 10 +#define I2C_MASTER_CH_TOTAL I2C_MASTER_CH_10 + +/* SPI_MASTER */ +#define SPI_MASTER_WR_EN 0x1200 /* one bit */ +#define SPI_MASTER_WR_DATA 0x1204 /* 32 bits */ +#define SPI_MASTER_CHK_ID 0x1208 /* one bit */ +#define SPI_MASTER_VERIFY 0x120c /* one bit */ +#define SPI_MASTER_STATUS 0x1210 /* 15 bits */ +#define SPI_MASTER_MODULE_RST 0x1214 /* one bit */ + +/* FPGA FRONT PANEL PORT MGMT */ +#define SFF_PORT_CTRL_BASE 0x4000 +#define SFF_PORT_STATUS_BASE 0x4004 +#define SFF_PORT_INT_STATUS_BASE 0x4008 +#define SFF_PORT_INT_MASK_BASE 0x400c + +#define PORT_XCVR_REGISTER_SIZE 0x1000 + +/* PORT CTRL REGISTER +[31:7] RSVD +[6] LPMOD 6 +[5] RSVD +[4] RST 4 +[3:1] RSVD +[0] TXDIS 0 +*/ +#define CTRL_LPMOD 6 +#define CTRL_RST 4 +#define CTRL_TXDIS 0 + +/* PORT STATUS REGISTER +[31:6] RSVD +[5] IRQ 5 +[4] PRESENT 4 +[3] RSVD +[2] TXFAULT 2 +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define STAT_IRQ 5 +#define STAT_PRESENT 4 +#define STAT_TXFAULT 2 +#define STAT_RXLOS 1 +#define STAT_MODABS 0 + +/* PORT INTRPT REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS 1 +[0] MODABS 0 +*/ +#define INTR_INT_N 5 +#define INTR_PRESENT 4 +#define INTR_TXFAULT 2 +#define INTR_RXLOS 1 +#define INTR_MODABS 0 + +/* PORT INT MASK REGISTER +[31:6] RSVD +[5] INT_N 5 +[4] PRESENT 4 +[3] RSVD +[2] RSVD +[1] RXLOS_INT 1 +[0] MODABS 0 +*/ +#define MASK_INT_N 5 +#define MASK_PRESENT 4 +#define MASK_TXFAULT 2 +#define MASK_RXLOS 1 +#define MASK_MODABS 0 + +enum { + I2C_SR_BIT_RXAK = 0, + I2C_SR_BIT_MIF, + I2C_SR_BIT_SRW, + I2C_SR_BIT_BCSTM, + I2C_SR_BIT_MAL, + I2C_SR_BIT_MBB, + I2C_SR_BIT_MAAS, + I2C_SR_BIT_MCF +}; + +enum { + I2C_CR_BIT_BCST = 0, + I2C_CR_BIT_RSTA = 2, + I2C_CR_BIT_TXAK, + I2C_CR_BIT_MTX, + I2C_CR_BIT_MSTA, + I2C_CR_BIT_MIEN, + I2C_CR_BIT_MEN, +}; + +/** + * + * The function is i2c algorithm implement to allow master access to + * correct endpoint devices trough the PCA9548 switch devices. + * + * FPGA I2C Master [mutex resource] + * | + * | + * --------------------------- + * | PCA9548(s) | + * ---1--2--3--4--5--6--7--8-- + * | | | | | | | | + * EEPROM ... EEPROM + * + */ + + +#ifdef SEASTONE2 +#define VIRTUAL_I2C_QSFP_PORT 32 +#define VIRTUAL_I2C_SFP_PORT 1 +#define VIRTUAL_I2C_CPLD_PORT 1 +#define VIRTUAL_I2C_POWER_CHIP_PORT 1 +#define VIRTUAL_I2C_CPLD_B_PORT 1 +#define VIRTUAL_I2C_PSU 1 +#define VIRTUAL_I2C_FAN_TRAY 4 +#define VIRTUAL_I2C_POWER_MON 1 +#define VIRTUAL_I2C_LM75 1 + +#define VIRTUAL_I2C_PORT_LENGTH \ + VIRTUAL_I2C_SFP_PORT+VIRTUAL_I2C_QSFP_PORT+VIRTUAL_I2C_POWER_CHIP_PORT+VIRTUAL_I2C_CPLD_PORT+VIRTUAL_I2C_CPLD_B_PORT+VIRTUAL_I2C_PSU+VIRTUAL_I2C_FAN_TRAY+VIRTUAL_I2C_POWER_MON+VIRTUAL_I2C_LM75 + +#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT+VIRTUAL_I2C_SFP_PORT +#else +#define VIRTUAL_I2C_SFP_PORT 48 +#define VIRTUAL_I2C_QSFP_PORT 8 +#define VIRTUAL_I2C_CPLD_PORT 1 +#define VIRTUAL_I2C_POWER_CHIP_PORT 1 +#define VIRTUAL_I2C_CPLD_B_PORT 1 +#define VIRTUAL_I2C_PSU 1 +#define VIRTUAL_I2C_FAN_TRAY 4 +#define VIRTUAL_I2C_POWER_MON 1 +#define VIRTUAL_I2C_LM75 1 + +#define VIRTUAL_I2C_PORT_LENGTH \ + VIRTUAL_I2C_SFP_PORT+VIRTUAL_I2C_QSFP_PORT+VIRTUAL_I2C_POWER_CHIP_PORT+VIRTUAL_I2C_CPLD_PORT+VIRTUAL_I2C_CPLD_B_PORT+VIRTUAL_I2C_PSU+VIRTUAL_I2C_FAN_TRAY+VIRTUAL_I2C_POWER_MON+VIRTUAL_I2C_LM75 + +#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT+VIRTUAL_I2C_SFP_PORT +#endif + +#define VIRTUAL_I2C_CPLD_INDEX SFF_PORT_TOTAL + +#define VIRTUAL_I2C_BUS_OFFSET 2 +#define CPLD1_SLAVE_ADDR 0x30 +#define CPLD2_SLAVE_ADDR 0x31 + +static struct class* fpgafwclass = NULL; ///< The device-driver class struct pointer +static struct device* fpgafwdev = NULL; ///< The device-driver device struct pointer + +#define PCI_VENDOR_ID_TEST 0x1af4 + +#ifndef PCI_VENDOR_ID_XILINX +#define PCI_VENDOR_ID_XILINX 0x10EE +#endif + +#define FPGA_PCIE_DEVICE_ID 0x7021 +#define TEST_PCIE_DEVICE_ID 0x1110 + + +#ifdef DEBUG_KERN +#define info(fmt,args...) printk(KERN_INFO "line %3d : "fmt,__LINE__,##args) +#define check(REG) printk(KERN_INFO "line %3d : %-8s = %2.2X",__LINE__,#REG,ioread8(REG)); +#else +#define info(fmt,args...) +#define check(REG) +#endif + +#define GET_REG_BIT(REG,BIT) ((ioread8(REG) >> BIT) & 0x01) +#define SET_REG_BIT_H(REG,BIT) iowrite8(ioread8(REG) | (0x01 << BIT),REG) +#define SET_REG_BIT_L(REG,BIT) iowrite8(ioread8(REG) & ~(0x01 << BIT),REG) + +static struct mutex fpga_i2c_master_locks[I2C_MASTER_CH_TOTAL]; +/* Store lasted switch address and channel */ +static uint16_t fpga_i2c_lasted_access_port[I2C_MASTER_CH_TOTAL]; + +enum PORT_TYPE { + NONE, + QSFP, + SFP +}; + +struct i2c_switch{ + unsigned char master_bus; // I2C bus number + unsigned char switch_addr; // PCA9548 device address, 0xFF if directly connect to a bus. + unsigned char channel; // PCA9548 channel number. If the switch_addr is 0xFF, this value is ignored. + enum PORT_TYPE port_type; // QSFP/SFP tranceiver port type. + char calling_name[20]; // Calling name. +}; + +struct i2c_dev_data { + int portid; + struct i2c_switch pca9548; +}; + +#ifdef SEASTONE2 +/* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ +static struct i2c_switch fpga_i2c_bus_dev[] = { + /* BUS2 QSFP Exported as virtual bus */ + {I2C_MASTER_CH_2,0x72,0,QSFP,"QSFP1"}, {I2C_MASTER_CH_2,0x72,1,QSFP,"QSFP2"}, {I2C_MASTER_CH_2,0x72,2,QSFP,"QSFP3"}, {I2C_MASTER_CH_2,0x72,3,QSFP,"QSFP4"}, + {I2C_MASTER_CH_2,0x72,4,QSFP,"QSFP5"}, {I2C_MASTER_CH_2,0x72,5,QSFP,"QSFP6"}, {I2C_MASTER_CH_2,0x72,6,QSFP,"QSFP7"}, {I2C_MASTER_CH_2,0x72,7,QSFP,"QSFP8"}, + {I2C_MASTER_CH_2,0x73,0,QSFP,"QSFP9"}, {I2C_MASTER_CH_2,0x73,1,QSFP,"QSFP10"},{I2C_MASTER_CH_2,0x73,2,QSFP,"QSFP11"},{I2C_MASTER_CH_2,0x73,3,QSFP,"QSFP12"}, + {I2C_MASTER_CH_2,0x73,4,QSFP,"QSFP13"},{I2C_MASTER_CH_2,0x73,5,QSFP,"QSFP14"},{I2C_MASTER_CH_2,0x73,6,QSFP,"QSFP15"},{I2C_MASTER_CH_2,0x73,7,QSFP,"QSFP16"}, + {I2C_MASTER_CH_2,0x74,0,QSFP,"QSFP17"},{I2C_MASTER_CH_2,0x74,1,QSFP,"QSFP18"},{I2C_MASTER_CH_2,0x74,2,QSFP,"QSFP19"},{I2C_MASTER_CH_2,0x74,3,QSFP,"QSFP20"}, + {I2C_MASTER_CH_2,0x74,4,QSFP,"QSFP21"},{I2C_MASTER_CH_2,0x74,5,QSFP,"QSFP22"},{I2C_MASTER_CH_2,0x74,6,QSFP,"QSFP23"},{I2C_MASTER_CH_2,0x74,7,QSFP,"QSFP24"}, + {I2C_MASTER_CH_2,0x75,0,QSFP,"QSFP25"},{I2C_MASTER_CH_2,0x75,1,QSFP,"QSFP26"},{I2C_MASTER_CH_2,0x75,2,QSFP,"QSFP27"},{I2C_MASTER_CH_2,0x75,3,QSFP,"QSFP28"}, + {I2C_MASTER_CH_2,0x75,4,QSFP,"QSFP29"},{I2C_MASTER_CH_2,0x75,5,QSFP,"QSFP30"},{I2C_MASTER_CH_2,0x75,6,QSFP,"QSFP31"},{I2C_MASTER_CH_2,0x75,7,QSFP,"QSFP32"}, + /* BUS1 SFP+ Exported as virtual bus */ + {I2C_MASTER_CH_1,0x72,0,SFP,"SFP1"},{I2C_MASTER_CH_1,0x72,1,SFP,"SFP2"}, + /* BUS3 CPLD Access via SYSFS */ + {I2C_MASTER_CH_3,0xFF,0,NONE,"CPLD"}, + /* BUS5 POWER CHIP Exported as virtual bus */ + {I2C_MASTER_CH_5,0xFF,0,NONE,"POWER"}, + /* BUS4 CPLD_B */ + {I2C_MASTER_CH_4,0xFF,0,NONE,"CPLD_B"}, + /* BUS6 PSU */ + {I2C_MASTER_CH_6,0xFF,0,NONE,"PSU"}, + /* BUS7 FAN */ + /* Channel 2 is no hardware connected */ + {I2C_MASTER_CH_7,0x77,0,NONE,"FAN5"},{I2C_MASTER_CH_7,0x77,1,NONE,"FAN4"},{I2C_MASTER_CH_7,0x77,3,NONE,"FAN2"},{I2C_MASTER_CH_7,0x77,4,NONE,"FAN1"}, + /* BUS8 POWER MONITOR */ + {I2C_MASTER_CH_8,0xFF,0,NONE,"UCD90120"}, + /* BUS9 LM75 */ + {I2C_MASTER_CH_9,0xFF,0,NONE,"LM75"}, +}; +#else +/* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ +static struct i2c_switch fpga_i2c_bus_dev[] = { + /* BUS1 SFP Exported as virtual bus */ + {I2C_MASTER_CH_10,0x72,0,SFP,"SFP1"}, {I2C_MASTER_CH_10,0x72,1,SFP,"SFP2"}, {I2C_MASTER_CH_10,0x72,2,SFP,"SFP3"}, {I2C_MASTER_CH_10,0x72,3,SFP,"SFP4"}, + {I2C_MASTER_CH_10,0x72,4,SFP,"SFP5"}, {I2C_MASTER_CH_10,0x72,5,SFP,"SFP6"}, {I2C_MASTER_CH_10,0x72,6,SFP,"SFP7"}, {I2C_MASTER_CH_10,0x72,7,SFP,"SFP8"}, + {I2C_MASTER_CH_10,0x73,0,SFP,"SFP9"}, {I2C_MASTER_CH_10,0x73,1,SFP,"SFP10"},{I2C_MASTER_CH_10,0x73,2,SFP,"SFP11"},{I2C_MASTER_CH_10,0x73,3,SFP,"SFP12"}, + {I2C_MASTER_CH_10,0x73,4,SFP,"SFP13"},{I2C_MASTER_CH_10,0x73,5,SFP,"SFP14"},{I2C_MASTER_CH_10,0x73,6,SFP,"SFP15"},{I2C_MASTER_CH_10,0x73,7,SFP,"SFP16"}, + {I2C_MASTER_CH_10,0x74,0,SFP,"SFP17"},{I2C_MASTER_CH_10,0x74,1,SFP,"SFP18"},{I2C_MASTER_CH_10,0x74,2,SFP,"SFP19"},{I2C_MASTER_CH_10,0x74,3,SFP,"SFP20"}, + {I2C_MASTER_CH_10,0x74,4,SFP,"SFP21"},{I2C_MASTER_CH_10,0x74,5,SFP,"SFP22"},{I2C_MASTER_CH_10,0x74,6,SFP,"SFP23"},{I2C_MASTER_CH_10,0x74,7,SFP,"SFP24"}, + {I2C_MASTER_CH_10,0x75,0,SFP,"SFP25"},{I2C_MASTER_CH_10,0x75,1,SFP,"SFP26"},{I2C_MASTER_CH_10,0x75,2,SFP,"SFP27"},{I2C_MASTER_CH_10,0x75,3,SFP,"SFP28"}, + {I2C_MASTER_CH_10,0x75,4,SFP,"SFP29"},{I2C_MASTER_CH_10,0x75,5,SFP,"SFP30"},{I2C_MASTER_CH_10,0x75,6,SFP,"SFP31"},{I2C_MASTER_CH_10,0x75,7,SFP,"SFP32"}, + {I2C_MASTER_CH_10,0x76,0,SFP,"SFP33"},{I2C_MASTER_CH_10,0x76,1,SFP,"SFP34"},{I2C_MASTER_CH_10,0x76,2,SFP,"SFP35"},{I2C_MASTER_CH_10,0x76,3,SFP,"SFP36"}, + {I2C_MASTER_CH_10,0x76,4,SFP,"SFP37"},{I2C_MASTER_CH_10,0x76,5,SFP,"SFP38"},{I2C_MASTER_CH_10,0x76,6,SFP,"SFP39"},{I2C_MASTER_CH_10,0x76,7,SFP,"SFP40"}, + {I2C_MASTER_CH_10,0x77,0,SFP,"SFP41"},{I2C_MASTER_CH_10,0x77,1,SFP,"SFP42"},{I2C_MASTER_CH_10,0x77,2,SFP,"SFP43"},{I2C_MASTER_CH_10,0x77,3,SFP,"SFP44"}, + {I2C_MASTER_CH_10,0x77,4,SFP,"SFP45"},{I2C_MASTER_CH_10,0x77,5,SFP,"SFP46"},{I2C_MASTER_CH_10,0x77,6,SFP,"SFP47"},{I2C_MASTER_CH_10,0x77,7,SFP,"SFP48"}, + /* BUS2 QSFP28 Exported as virtual bus */ + {I2C_MASTER_CH_2,0x74,4,QSFP,"QSFP1"},{I2C_MASTER_CH_2,0x74,5,QSFP,"QSFP2"},{I2C_MASTER_CH_2,0x74,6,QSFP,"QSFP3"},{I2C_MASTER_CH_2,0x74,7,QSFP,"QSFP4"}, + {I2C_MASTER_CH_2,0x74,0,QSFP,"QSFP5"},{I2C_MASTER_CH_2,0x74,1,QSFP,"QSFP6"},{I2C_MASTER_CH_2,0x74,2,QSFP,"QSFP7"},{I2C_MASTER_CH_2,0x74,3,QSFP,"QSFP8"}, + /* BUS3 CPLD Access via SYSFS */ + {I2C_MASTER_CH_3,0xFF,0,NONE,"CPLD"}, + /* BUS5 POWER CHIP Exported as virtual bus */ + {I2C_MASTER_CH_5,0xFF,0,NONE,"POWER"}, + /* BUS4 CPLD_B */ + {I2C_MASTER_CH_4,0xFF,0,NONE,"CPLD_B"}, + /* BUS6 PSU */ + {I2C_MASTER_CH_6,0xFF,0,NONE,"PSU"}, + /* BUS7 FAN */ + /* Channel 2 is no hardware connected */ + {I2C_MASTER_CH_7,0x77,0,NONE,"FAN5"},{I2C_MASTER_CH_7,0x77,1,NONE,"FAN4"},{I2C_MASTER_CH_7,0x77,3,NONE,"FAN2"},{I2C_MASTER_CH_7,0x77,4,NONE,"FAN1"}, + /* BUS8 UCD90120 */ + {I2C_MASTER_CH_8,0xFF,0,NONE,"UCD90120"}, + /* BUS9 TEMP SENSOR LM75 */ + {I2C_MASTER_CH_9,0xFF,0,NONE,"LM75"} +}; +#endif +struct fpga_device{ + /* data mmio region */ + void __iomem *data_base_addr; + resource_size_t data_mmio_start; + resource_size_t data_mmio_len; +}; + +static struct fpga_device fpga_dev = { + .data_base_addr = NULL, + .data_mmio_start = NULL, + .data_mmio_len = NULL, +}; + +struct seastone2_fpga_data { + struct device *sff_devices[SFF_PORT_TOTAL]; + struct i2c_client *sff_i2c_clients[SFF_PORT_TOTAL]; + struct i2c_adapter *i2c_adapter[VIRTUAL_I2C_PORT_LENGTH]; + struct mutex fpga_lock; // For FPGA internal lock + unsigned long fpga_read_addr; + uint8_t cpld1_read_addr; + uint8_t cpld2_read_addr; +}; + +struct sff_device_data { + int portid; + enum PORT_TYPE port_type; +}; + +struct seastone2_fpga_data *fpga_data; + +/* + * Kernel object for other module drivers. + * Other module can use these kobject as a parent. + */ + +static struct kobject *fpga = NULL; +static struct kobject *cpld1 = NULL; +static struct kobject *cpld2 = NULL; + +/** + * Device node in sysfs tree. + */ +static struct device *sff_dev = NULL; + +/** + * [get_fpga_reg_value description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @return [description] + */ +static ssize_t get_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + // read data from the address + uint32_t data; + data = ioread32(fpga_data->fpga_read_addr); + return sprintf(buf,"0x%8.8x\n",data); +} +/** + * [set_fpga_reg_address description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @param count [description] + * @return [description] + */ +static ssize_t set_fpga_reg_address(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t addr; + char *last; + + addr = (uint32_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + fpga_data->fpga_read_addr = fpga_dev.data_base_addr+addr; + return count; +} +/** + * [get_fpga_scratch description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @return [description] + */ +static ssize_t get_fpga_scratch(struct device *dev, struct device_attribute *devattr, + char *buf) +{ + return sprintf(buf,"0x%8.8x\n", ioread32(fpga_dev.data_base_addr+FPGA_SCRATCH) & 0xffffffff); +} +/** + * [set_fpga_scratch description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @param count [description] + * @return [description] + */ +static ssize_t set_fpga_scratch(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + uint32_t data; + char *last; + data = (uint32_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + return -EINVAL; + } + iowrite32(data, fpga_dev.data_base_addr+FPGA_SCRATCH); + return count; +} +/** + * [set_fpga_reg_value description] + * @param dev [description] + * @param devattr [description] + * @param buf [description] + * @return [description] + */ +static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *devattr, + const char *buf, size_t count) +{ + //register is 4 bytes + uint32_t addr; + uint32_t value; + uint32_t mode = 8; + char *tok; + char clone[count]; + char *pclone = clone; + char *last; + + strcpy(clone, buf); + + mutex_lock(&fpga_data->fpga_lock); + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + addr = (uint32_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + value = (uint32_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + mode = 32; + }else{ + mode = (uint32_t)strtoul(tok,&last,10); + if(mode == 0 && tok == last){ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + } + if(mode == 32){ + iowrite32(value, fpga_dev.data_base_addr+addr); + }else if(mode == 8){ + iowrite8(value, fpga_dev.data_base_addr+addr); + }else{ + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return count; +} + +/** + * Read all FPGA XCVR register in binary mode. + * @param filp [description] + * @param kobj [description] + * @param attr [description] + * @param buf [description] + * @param off [description] + * @param count [description] + * @return [description] + */ +static ssize_t dump_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) +{ + unsigned long i=0; + ssize_t status; + u8 read_reg; + + if( off + count > PORT_XCVR_REGISTER_SIZE ){ + return -EINVAL; + } + mutex_lock(&fpga_data->fpga_lock); + while(i < count){ + read_reg = ioread8(fpga_dev.data_base_addr + SFF_PORT_CTRL_BASE + off + i); + buf[i++] = read_reg; + } + status = count; + mutex_unlock(&fpga_data->fpga_lock); + return status; +} + +/** + * Show FPGA port XCVR ready status + * @param dev [description] + * @param attr [description] + * @param buf [description] + * @return [description] + */ +static ssize_t ready_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int REGISTER = FPGA_PORT_XCVR_READY; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> 0) & 1U); +} + +/* FPGA attributes */ +static DEVICE_ATTR( getreg, 0600, get_fpga_reg_value, set_fpga_reg_address); +static DEVICE_ATTR( scratch, 0600, get_fpga_scratch, set_fpga_scratch); +static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); +static DEVICE_ATTR_RO(ready); +static BIN_ATTR_RO( dump, PORT_XCVR_REGISTER_SIZE); + +static struct bin_attribute *fpga_bin_attrs[] = { + &bin_attr_dump, + NULL, +}; + +static struct attribute *fpga_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_scratch.attr, + &dev_attr_setreg.attr, + &dev_attr_ready.attr, + NULL, +}; + +static struct attribute_group fpga_attr_grp = { + .attrs = fpga_attrs, + .bin_attrs = fpga_bin_attrs, +}; + +/* SW CPLDs attributes */ +static ssize_t cpld1_getreg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD1_SLAVE_ADDR, 0x00, + I2C_SMBUS_READ, fpga_data->cpld1_read_addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld1_getreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + ssize_t status; + uint8_t addr; + + status = kstrtou8(buf, 0, &addr); + if (status == 0) { + fpga_data->cpld1_read_addr = addr; + status = count; + } + return status; +} +struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg, 0600, cpld1_getreg_show, cpld1_getreg_store); + +static ssize_t cpld1_dump_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,fpga_data->cpld1_read_addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + return sprintf(buf,"0x%2.2x\n",data); +} +static ssize_t cpld1_dump_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + uint8_t addr; + char *last; + addr = (uint8_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + fpga_data->cpld1_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld1_dump = __ATTR(dump,0600,cpld1_dump_show,cpld1_dump_store); + +static ssize_t cpld1_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + __u8 data; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + if(err < 0) + return err; + return sprintf(buf, "0x%2.2x\n",data); +} +static ssize_t cpld1_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + __u8 data; + char *last; + int err; + data = (uint8_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + if(err < 0) + return err; + return size; +} +struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch,0600,cpld1_scratch_show,cpld1_scratch_store); + +static ssize_t cpld1_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + + uint8_t addr,value; + char *tok; + char clone[size]; + char *pclone = clone; + int err; + char *last; + + strcpy(clone, buf); + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + return sprintf(buf,"ERROR line %d",__LINE__); + } + addr = (uint8_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + return sprintf(buf,"ERROR line %d",__LINE__); + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&value); + if(err < 0) + return sprintf(buf,"ERROR line %d",__LINE__); + + return size; +} +struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg,0200,NULL,cpld1_setreg_store); + +static struct attribute *cpld1_attrs[] = { + &dev_attr_cpld1_getreg.attr, + &dev_attr_cpld1_dump.attr, + &dev_attr_cpld1_scratch.attr, + &dev_attr_cpld1_setreg.attr, + NULL, +}; + +static struct attribute_group cpld1_attr_grp = { + .attrs = cpld1_attrs, +}; + +static ssize_t cpld2_getreg_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + int err; + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX], + CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld2_read_addr, + I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); + if (err < 0) + return err; + + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t cpld2_getreg_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + // CPLD register is one byte + uint8_t addr; + ssize_t status; + + status = kstrtou8(buf, 0, &addr); + if (status == 0) { + fpga_data->cpld2_read_addr = addr; + status = count; + } + return status; +} +struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg, 0600, cpld2_getreg_show, cpld2_getreg_store); + +static ssize_t cpld2_dump_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + uint8_t data; + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,fpga_data->cpld2_read_addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + return sprintf(buf,"0x%2.2x\n",data); +} +static ssize_t cpld2_dump_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + uint32_t addr; + char *last; + addr = (uint8_t)strtoul(buf,&last,16); + if(addr == 0 && buf == last){ + return -EINVAL; + } + fpga_data->cpld2_read_addr = addr; + return size; +} +struct device_attribute dev_attr_cpld2_dump = __ATTR(dump,0600,cpld2_dump_show,cpld2_dump_store); + +static ssize_t cpld2_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // CPLD register is one byte + __u8 data; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + if(err < 0) + return err; + return sprintf(buf, "0x%2.2x\n",data); +} +static ssize_t cpld2_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + // CPLD register is one byte + __u8 data; + char *last; + int err; + + data = (uint8_t)strtoul(buf,&last,16); + if(data == 0 && buf == last){ + return -EINVAL; + } + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,0x01,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&data); + if(err < 0) + return err; + return size; +} +struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch,0600,cpld2_scratch_show,cpld2_scratch_store); + +static ssize_t cpld2_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + uint8_t addr,value; + char *tok; + char clone[size]; + char *pclone = clone; + int err; + char *last; + + strcpy(clone, buf); + + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + return -EINVAL; + } + addr = (uint8_t)strtoul(tok,&last,16); + if(addr == 0 && tok == last){ + return -EINVAL; + } + tok = strsep((char**)&pclone, " "); + if(tok == NULL){ + return -EINVAL; + } + value = (uint8_t)strtoul(tok,&last,16); + if(value == 0 && tok == last){ + return -EINVAL; + } + + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_WRITE,addr,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&value); + if(err < 0) + return err; + + return size; +} +struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg,0200,NULL,cpld2_setreg_store); + +static struct attribute *cpld2_attrs[] = { + &dev_attr_cpld2_getreg.attr, + &dev_attr_cpld2_dump.attr, + &dev_attr_cpld2_scratch.attr, + &dev_attr_cpld2_setreg.attr, + NULL, +}; + +static struct attribute_group cpld2_attr_grp = { + .attrs = cpld2_attrs, +}; + +/* QSFP/SFP+ attributes */ +static ssize_t qsfp_modirq_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_IRQ) & 1U); +} +DEVICE_ATTR_RO(qsfp_modirq); + +static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_PRESENT) & 1U); +} +DEVICE_ATTR_RO(qsfp_modprs); + +static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_TXFAULT) & 1U); +} +DEVICE_ATTR_RO(sfp_txfault); + +static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_RXLOS) & 1U); +} +DEVICE_ATTR_RO(sfp_rxlos); + +static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> STAT_MODABS) & 1U); +} +DEVICE_ATTR_RO(sfp_modabs); + +static ssize_t qsfp_lpmode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_LPMOD) & 1U); +} +static ssize_t qsfp_lpmode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr+REGISTER); + if(!value) + data = data & ~( (u32)0x1 << CTRL_LPMOD); + else + data = data | ((u32)0x1 << CTRL_LPMOD); + iowrite32(data,fpga_dev.data_base_addr+REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_lpmode); + +static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_RST) & 1U); +} + +static ssize_t qsfp_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr+REGISTER); + if(!value) + data = data & ~( (u32)0x1 << CTRL_RST); + else + data = data | ((u32)0x1 << CTRL_RST); + iowrite32(data,fpga_dev.data_base_addr+REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(qsfp_reset); + +static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + data = ioread32(fpga_dev.data_base_addr+REGISTER); + mutex_unlock(&fpga_data->fpga_lock); + return sprintf(buf, "%d\n", (data >> CTRL_TXDIS) & 1U); +} +static ssize_t sfp_txdisable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + ssize_t status; + long value; + u32 data; + struct sff_device_data *dev_data = dev_get_drvdata(dev); + unsigned int portid = dev_data->portid; + unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid-1)*0x10; + + mutex_lock(&fpga_data->fpga_lock); + status = kstrtol(buf, 0, &value); + if (status == 0) { + // check if value is 0 clear + data = ioread32(fpga_dev.data_base_addr+REGISTER); + if(!value) + data = data & ~( (u32)0x1 << CTRL_TXDIS); + else + data = data | ((u32)0x1 << CTRL_TXDIS); + iowrite32(data,fpga_dev.data_base_addr+REGISTER); + status = size; + } + mutex_unlock(&fpga_data->fpga_lock); + return status; +} +DEVICE_ATTR_RW(sfp_txdisable); + +static struct attribute *sff_attrs[] = { + &dev_attr_qsfp_modirq.attr, + &dev_attr_qsfp_modprs.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_reset.attr, + &dev_attr_sfp_txfault.attr, + &dev_attr_sfp_rxlos.attr, + &dev_attr_sfp_modabs.attr, + &dev_attr_sfp_txdisable.attr, + NULL, +}; + +static struct attribute_group sff_attr_grp = { + .attrs = sff_attrs, +}; + +static const struct attribute_group *sff_attr_grps[] = { + &sff_attr_grp, + NULL +}; + + +static ssize_t port_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // value can be "nomal", "test" + __u8 led_mode_1,led_mode_2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); + if(err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_2); + if(err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal"); +} +static ssize_t port_led_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int status; + __u8 led_mode_1; + if(sysfs_streq(buf, "test")){ + led_mode_1 = 0x01; + }else if(sysfs_streq(buf, "normal")){ + led_mode_1 = 0x00; + }else{ + return -EINVAL; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, + I2C_SMBUS_WRITE,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, + I2C_SMBUS_WRITE,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_mode_1); + return size; +} +DEVICE_ATTR_RW(port_led_mode); + +// Only work when port_led_mode set to 1 +static ssize_t port_led_color_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + // value can be "off", "green", "amber", "both" + __u8 led_color1,led_color2; + int err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color1); + if(err < 0) + return err; + err = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00,I2C_SMBUS_READ,0x09,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color2); + if(err < 0) + return err; + return sprintf(buf, "%s %s\n", + led_color1 == 0x03 ? "off" : led_color1 == 0x02 ? "green" : led_color1 ==0x01 ? "amber": "both", + led_color2 == 0x03 ? "off" : led_color2 == 0x02 ? "green" : led_color2 ==0x01 ? "amber": "both"); +} + +static ssize_t port_led_color_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) +{ + int status; + __u8 led_color; + if(sysfs_streq(buf, "off")){ + led_color = 0x03; + }else if(sysfs_streq(buf, "green")){ + led_color = 0x02; + }else if(sysfs_streq(buf, "amber")){ + led_color = 0x01; + }else if(sysfs_streq(buf, "both")){ + led_color = 0x00; + }else{ + status = -EINVAL; + return status; + } + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, + I2C_SMBUS_WRITE,0x0A,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color); + status = fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, + I2C_SMBUS_WRITE,0x0A,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&led_color); + return size; +} +DEVICE_ATTR_RW(port_led_color); + +static struct attribute *sff_led_test[] = { + &dev_attr_port_led_mode.attr, + &dev_attr_port_led_color.attr, + NULL, +}; + +static struct attribute_group sff_led_test_grp = { + .attrs = sff_led_test, +}; + +static struct device * seastone2_sff_init(int portid){ + struct sff_device_data *new_data; + struct device *new_device; + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data) { + printk(KERN_ALERT "Cannot alloc sff device data @port%d", portid); + return NULL; + } + /* The QSFP port ID start from 1 */ + new_data->portid = portid+1; + new_data->port_type = fpga_i2c_bus_dev[portid].port_type; + new_device = device_create_with_groups(fpgafwclass, sff_dev, MKDEV(0,0), new_data, sff_attr_grps, "%s",fpga_i2c_bus_dev[portid].calling_name); + if (IS_ERR(new_device)) { + printk(KERN_ALERT "Cannot create sff device @port%d", portid); + kfree(new_data); + return NULL; + } + return new_device; +} + +static int i2c_wait_ack(struct i2c_adapter *a,unsigned long timeout,int writing){ + int error = 0; + int Status; + + struct i2c_dev_data *new_data = i2c_get_adapdata(a); + void __iomem *pci_bar = fpga_dev.data_base_addr; + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + unsigned int master_bus = new_data->pca9548.master_bus; + + if(master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL){ + error = -ENXIO; + return error; + } + + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus-1)*0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus-1)*0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus-1)*0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus-1)*0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus-1)*0x0100; + + check(pci_bar+REG_SR0); + check(pci_bar+REG_CR0); + + timeout = jiffies + msecs_to_jiffies(timeout); + while(1){ + Status = ioread8(pci_bar+REG_SR0); + if(jiffies > timeout){ + info("Status %2.2X",Status); + info("Error Timeout"); + error = -ETIMEDOUT; + break; + } + + + if(Status & (1 << I2C_SR_BIT_MIF)){ + break; + } + + if(writing == 0 && (Status & (1<portid; + void __iomem *pci_bar = fpga_dev.data_base_addr; + +#ifdef DEBUG_KERN + printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-15s|CMD %2.2X " + ,portid,addr,flags,rw,rw == 1 ? "READ ":"WRITE" + ,size, size == 0 ? "QUICK" : + size == 1 ? "BYTE" : + size == 2 ? "BYTE_DATA" : + size == 3 ? "WORD_DATA" : + size == 4 ? "PROC_CALL" : + size == 5 ? "BLOCK_DATA" : + size == 8 ? "I2C_BLOCK_DATA" : "ERROR" + ,cmd); +#endif + /* Map the size to what the chip understands */ + switch (size) { + case I2C_SMBUS_QUICK: + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + break; + default: + printk(KERN_INFO "Unsupported transaction %d\n", size); + error = -EOPNOTSUPP; + goto Done; + } + + unsigned int REG_FDR0; + unsigned int REG_CR0; + unsigned int REG_SR0; + unsigned int REG_DR0; + unsigned int REG_ID0; + + unsigned int master_bus = dev_data->pca9548.master_bus; + + if(master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL){ + error = -ENXIO; + goto Done; + } + + REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus-1)*0x0100; + REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus-1)*0x0100; + REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus-1)*0x0100; + REG_DR0 = I2C_MASTER_DATA_1 + (master_bus-1)*0x0100; + REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus-1)*0x0100; + + iowrite8(portid,pci_bar+REG_ID0); + + int cnt=0; + + ////[S][ADDR/R] + // Clear status register + iowrite8(0,pci_bar+REG_SR0); + iowrite8(1 << I2C_CR_BIT_MIEN | 1 << I2C_CR_BIT_MTX | 1 << I2C_CR_BIT_MSTA ,pci_bar+REG_CR0); + SET_REG_BIT_H(pci_bar+REG_CR0,I2C_CR_BIT_MEN); + + if(rw == I2C_SMBUS_READ && + (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)){ + // sent device address with Read mode + iowrite8(addr << 1 | 0x01,pci_bar+REG_DR0); + }else{ + // sent device address with Write mode + iowrite8(addr << 1 | 0x00,pci_bar+REG_DR0); + } + + + + info( "MS Start"); + + //// Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + + //// [CMD]{A} + if(size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA || + (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)){ + + // sent command code to data register + iowrite8(cmd,pci_bar+REG_DR0); + info( "MS Send CMD 0x%2.2X",cmd); + + // Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + } + + switch(size){ + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + case I2C_SMBUS_I2C_BLOCK_DATA: + /* In block data modes keep number of byte in block[0] */ + cnt = data->block[0]; + break; + default: + cnt = 0; break; + } + + // [CNT] used only block data write + if(size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE){ + + iowrite8(cnt,pci_bar+REG_DR0); + info( "MS Send CNT 0x%2.2X",cnt); + + // Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + info( "get error %d",error); + goto Done; + } + } + + // [DATA]{A} + if( rw == I2C_SMBUS_WRITE && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )){ + int bid=0; + info( "MS prepare to sent [%d bytes]",cnt); + if(size == I2C_SMBUS_BLOCK_DATA || size == I2C_SMBUS_I2C_BLOCK_DATA){ + bid=1; // block[0] is cnt; + cnt+=1; // offset from block[0] + } + for(;bidblock[bid],pci_bar+REG_DR0); + info( " Data > %2.2X",data->block[bid]); + // Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + goto Done; + } + } + + } + + // REPEATE START + if( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )){ + info( "MS Repeated Start"); + + SET_REG_BIT_L(pci_bar+REG_CR0,I2C_CR_BIT_MEN); + iowrite8(1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MTX | + 1 << I2C_CR_BIT_MSTA | + 1 << I2C_CR_BIT_RSTA ,pci_bar+REG_CR0); + SET_REG_BIT_H(pci_bar+REG_CR0,I2C_CR_BIT_MEN); + + // sent Address with Read mode + iowrite8( addr<<1 | 0x1 ,pci_bar+REG_DR0); + + // Wait {A} + error = i2c_wait_ack(adapter,12,1); + if(error<0){ + goto Done; + } + + } + + if( rw == I2C_SMBUS_READ && ( + size == I2C_SMBUS_BYTE || + size == I2C_SMBUS_BYTE_DATA || + size == I2C_SMBUS_WORD_DATA || + size == I2C_SMBUS_BLOCK_DATA || + size == I2C_SMBUS_I2C_BLOCK_DATA + )){ + + switch(size){ + case I2C_SMBUS_BYTE: + case I2C_SMBUS_BYTE_DATA: + cnt = 1; break; + case I2C_SMBUS_WORD_DATA: + cnt = 2; break; + case I2C_SMBUS_BLOCK_DATA: + // will be changed after recived first data + cnt = 3; break; + case I2C_SMBUS_I2C_BLOCK_DATA: + cnt = data->block[0]; break; + default: + cnt = 0; break; + } + + int bid = 0; + info( "MS Receive"); + + //set to Receive mode + iowrite8(1 << I2C_CR_BIT_MEN | + 1 << I2C_CR_BIT_MIEN | + 1 << I2C_CR_BIT_MSTA , pci_bar+REG_CR0); + + for(bid=-1;bidblock[bid+1] = ioread8(pci_bar+REG_DR0); + }else { + data->block[bid] = ioread8(pci_bar+REG_DR0); + } + info( "DATA IN [%d] %2.2X",bid,data->block[bid]); + + if(size == I2C_SMBUS_BLOCK_DATA && bid == 0){ + cnt = data->block[0] + 1; + } + } + } + } + +Stop: + // [P] + SET_REG_BIT_L(pci_bar+REG_CR0,I2C_CR_BIT_MSTA); + info( "MS STOP"); + +Done: + iowrite8(1<pca9548.master_bus; + unsigned char switch_addr = dev_data->pca9548.switch_addr; + unsigned char channel = dev_data->pca9548.channel; + + // Acquire the master resource. + mutex_lock(&fpga_i2c_master_locks[master_bus-1]); + uint16_t prev_port = fpga_i2c_lasted_access_port[master_bus-1]; + + if(switch_addr != 0xFF){ + // Check lasted access switch address on a master + if((unsigned char)(prev_port >> 8) == switch_addr){ + // check if channel is the same + if((unsigned char)(prev_port & 0x00FF) != channel){ + // set new PCA9548 at switch_addr to current + error= smbus_access(adapter,switch_addr,flags,I2C_SMBUS_WRITE,1 << channel,I2C_SMBUS_BYTE,NULL); + // update lasted port + fpga_i2c_lasted_access_port[master_bus-1] = switch_addr << 8 | channel; + } + }else{ + // reset prev_port PCA9548 chip + error= smbus_access(adapter,(u16)(prev_port >> 8),flags,I2C_SMBUS_WRITE,0x00,I2C_SMBUS_BYTE,NULL); + // set PCA9548 to current channel + error= smbus_access(adapter,switch_addr,flags,I2C_SMBUS_WRITE,1 << channel,I2C_SMBUS_BYTE,NULL); + // update lasted port + fpga_i2c_lasted_access_port[master_bus-1] = switch_addr << 8 | channel; + } + } + + // Do SMBus communication + error = smbus_access(adapter,addr,flags,rw,cmd,size,data); + // reset the channel + mutex_unlock(&fpga_i2c_master_locks[master_bus-1]); + return error; +} + + + +/** + * A callback function show available smbus functions. + */ +static u32 fpga_i2c_func(struct i2c_adapter *a) +{ + return I2C_FUNC_SMBUS_QUICK | + I2C_FUNC_SMBUS_BYTE | + I2C_FUNC_SMBUS_BYTE_DATA | + I2C_FUNC_SMBUS_WORD_DATA | + I2C_FUNC_SMBUS_BLOCK_DATA| + I2C_FUNC_SMBUS_I2C_BLOCK; +} + +static const struct i2c_algorithm seastone2_i2c_algorithm = { + .smbus_xfer = fpga_i2c_access, + .functionality = fpga_i2c_func, +}; + +/** + * Create virtual I2C bus adapter for switch devices + * @param pdev platform device pointer + * @param portid virtual i2c port id for switch device mapping + * @param bus_number_offset bus offset for virtual i2c adapter in system + * @return i2c adapter. + * + * When bus_number_offset is -1, created adapter with dynamic bus number. + * Otherwise create adapter at i2c bus = bus_number_offset + portid. + */ +static struct i2c_adapter * seastone2_i2c_init(struct platform_device *pdev, int portid, int bus_number_offset) +{ + int error; + + struct i2c_adapter *new_adapter; + struct i2c_dev_data *new_data; + + new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); + if (!new_adapter){ + printk(KERN_ALERT "Cannot alloc i2c adapter for %s", fpga_i2c_bus_dev[portid].calling_name); + return NULL; + } + + new_adapter->owner = THIS_MODULE; + new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; + new_adapter->algo = &seastone2_i2c_algorithm; + /* If the bus offset is -1, use dynamic bus number */ + if (bus_number_offset == -1){ + new_adapter->nr = -1; + }else{ + new_adapter->nr = bus_number_offset + portid; + } + + new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); + if (!new_data){ + printk(KERN_ALERT "Cannot alloc i2c data for %s", fpga_i2c_bus_dev[portid].calling_name); + kfree_sensitive(new_adapter); + return NULL; + } + + new_data->portid = portid; + new_data->pca9548.master_bus = fpga_i2c_bus_dev[portid].master_bus; + new_data->pca9548.switch_addr = fpga_i2c_bus_dev[portid].switch_addr; + new_data->pca9548.channel = fpga_i2c_bus_dev[portid].channel; + strcpy(new_data->pca9548.calling_name,fpga_i2c_bus_dev[portid].calling_name); + + snprintf(new_adapter->name, sizeof(new_adapter->name), + "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); + + void __iomem *i2c_freq_base_reg = fpga_dev.data_base_addr+I2C_MASTER_FREQ_1; + iowrite8(0x07,i2c_freq_base_reg+(new_data->pca9548.master_bus-1)*0x100); // 0x07 400kHz + i2c_set_adapdata(new_adapter,new_data); + error = i2c_add_numbered_adapter(new_adapter); + if(error < 0){ + printk(KERN_ALERT "Cannot add i2c adapter %s", new_data->pca9548.calling_name); + kfree_sensitive(new_adapter); + kfree_sensitive(new_data); + return NULL; + } + + return new_adapter; +}; + +// I/O resource need. +static struct resource seastone2_resources[] = { + { + .start = 0x10000000, + .end = 0x10001000, + .flags = IORESOURCE_MEM, + }, +}; + +static void seastone2_dev_release( struct device * dev) +{ + return; +} + +static struct platform_device seastone2_dev = { + .name = DRIVER_NAME, + .id = -1, + .num_resources = ARRAY_SIZE(seastone2_resources), + .resource = seastone2_resources, + .dev = { + .release = seastone2_dev_release, + } +}; + +/** + * Board info for QSFP/SFP+ eeprom. + * Note: Using sff8436 as I2C eeprom driver. + */ +static struct i2c_board_info sff8436_eeprom_info[] = { + { I2C_BOARD_INFO("optoe1", 0x50) }, + { I2C_BOARD_INFO("optoe2", 0x50) }, +}; + +static int seastone2_drv_probe(struct platform_device *pdev) +{ + struct resource *res; + int ret = 0; + int portid_count; + uint8_t cpld1_version, cpld2_version; + uint16_t prev_i2c_switch = 0; + + /* The device class need to be instantiated before this function called */ + BUG_ON(fpgafwclass == NULL); + + fpga_data = devm_kzalloc(&pdev->dev, sizeof(struct seastone2_fpga_data), + GFP_KERNEL); + + if (!fpga_data) + return -ENOMEM; + + // Set default read address to VERSION + fpga_data->fpga_read_addr = fpga_dev.data_base_addr+FPGA_VERSION; + fpga_data->cpld1_read_addr = 0x00; + fpga_data->cpld2_read_addr = 0x00; + + mutex_init(&fpga_data->fpga_lock); + for(ret=I2C_MASTER_CH_1 ;ret <= I2C_MASTER_CH_TOTAL; ret++){ + mutex_init(&fpga_i2c_master_locks[ret-1]); + } + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (unlikely(!res)) { + printk(KERN_ERR "Specified Resource Not Available...\n"); + kfree_sensitive(fpga_data); + return -1; + } + + fpga = kobject_create_and_add("FPGA", &pdev->dev.kobj); + if (!fpga){ + kfree_sensitive(fpga_data); + return -ENOMEM; + } + + ret = sysfs_create_group(fpga, &fpga_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create FPGA sysfs attributes\n"); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + cpld1 = kobject_create_and_add("CPLD1", &pdev->dev.kobj); + if (!cpld1){ + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld1, &cpld1_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD1 sysfs attributes\n"); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + cpld2 = kobject_create_and_add("CPLD2", &pdev->dev.kobj); + if (!cpld2){ + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return -ENOMEM; + } + ret = sysfs_create_group(cpld2, &cpld2_attr_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create CPLD2 sysfs attributes\n"); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + sff_dev = device_create(fpgafwclass, NULL, MKDEV(0,0), NULL, "sff_device"); + if (IS_ERR(sff_dev)){ + printk(KERN_ERR "Failed to create sff device\n"); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return PTR_ERR(sff_dev); + } + + ret = sysfs_create_group(&sff_dev->kobj, &sff_led_test_grp); + if (ret != 0) { + printk(KERN_ERR "Cannot create SFF attributes\n"); + device_destroy(fpgafwclass, MKDEV(0,0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + ret = sysfs_create_link(&pdev->dev.kobj,&sff_dev->kobj,"SFF"); + if (ret != 0){ + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + device_destroy(fpgafwclass, MKDEV(0,0)); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + kobject_put(cpld2); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + kobject_put(cpld1); + sysfs_remove_group(fpga, &fpga_attr_grp); + kobject_put(fpga); + kfree_sensitive(fpga_data); + return ret; + } + + for(portid_count=0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++){ + fpga_data->i2c_adapter[portid_count] = seastone2_i2c_init(pdev, portid_count, VIRTUAL_I2C_BUS_OFFSET); + } + + + /* Init SFF devices */ + for(portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ + struct i2c_adapter *i2c_adap = fpga_data->i2c_adapter[portid_count]; + if(i2c_adap){ + fpga_data->sff_devices[portid_count] = seastone2_sff_init(portid_count); + struct sff_device_data *sff_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + BUG_ON(sff_data == NULL); + if( sff_data->port_type == QSFP ){ + fpga_data->sff_i2c_clients[portid_count] = i2c_new_client_device(i2c_adap, &sff8436_eeprom_info[0]); + }else{ + fpga_data->sff_i2c_clients[portid_count] = i2c_new_client_device(i2c_adap, &sff8436_eeprom_info[1]); + } + sff_data = NULL; + sysfs_create_link(&fpga_data->sff_devices[portid_count]->kobj, + &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, + "i2c"); + } + + } + + printk(KERN_INFO "Virtual I2C buses created\n"); + +#ifdef TEST_MODE + return 0; +#endif + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD1_SLAVE_ADDR,0x00, + I2C_SMBUS_READ,0x00,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&cpld1_version); + fpga_i2c_access(fpga_data->i2c_adapter[VIRTUAL_I2C_CPLD_INDEX],CPLD2_SLAVE_ADDR,0x00, + I2C_SMBUS_READ,0x00,I2C_SMBUS_BYTE_DATA,(union i2c_smbus_data*)&cpld2_version); + + printk(KERN_INFO "CPLD1 VERSON: %2.2x\n", cpld1_version); + printk(KERN_INFO "CPLD2 VERSON: %2.2x\n", cpld2_version); + + /* Init I2C buses that has PCA9548 switch device. */ + for(portid_count = 0; portid_count < VIRTUAL_I2C_PORT_LENGTH; portid_count++){ + + struct i2c_dev_data *dev_data; + dev_data = i2c_get_adapdata(fpga_data->i2c_adapter[portid_count]); + unsigned char master_bus = dev_data->pca9548.master_bus; + unsigned char switch_addr = dev_data->pca9548.switch_addr; + unsigned char channel = dev_data->pca9548.channel; + + if(switch_addr != 0xFF){ + + if(prev_i2c_switch != ( (master_bus << 8) | switch_addr) ){ + // Found the bus with PCA9548, trying to clear all switch in it. + smbus_access(fpga_data->i2c_adapter[portid_count],switch_addr,0x00,I2C_SMBUS_WRITE,0x00,I2C_SMBUS_BYTE,NULL); + prev_i2c_switch = ( master_bus << 8 ) | switch_addr; + } + } + } + return 0; +} + +static int seastone2_drv_remove(struct platform_device *pdev) +{ + int portid_count; + struct sff_device_data *rem_data; + + for(portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ + sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj,"i2c"); + i2c_unregister_device(fpga_data->sff_i2c_clients[portid_count]); + } + + for(portid_count=0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++){ + if(fpga_data->i2c_adapter[portid_count] != NULL){ + info(KERN_INFO "<%x>",fpga_data->i2c_adapter[portid_count]); + i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); + } + } + + for (portid_count=0; portid_count < SFF_PORT_TOTAL; portid_count++){ + if(fpga_data->sff_devices[portid_count] != NULL){ + rem_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); + device_unregister(fpga_data->sff_devices[portid_count]); + put_device(fpga_data->sff_devices[portid_count]); + kfree(rem_data); + } + } + + sysfs_remove_group(fpga, &fpga_attr_grp); + sysfs_remove_group(cpld1, &cpld1_attr_grp); + sysfs_remove_group(cpld2, &cpld2_attr_grp); + sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); + kobject_put(fpga); + kobject_put(cpld1); + kobject_put(cpld2); + device_destroy(fpgafwclass, MKDEV(0,0)); + devm_kfree(&pdev->dev, fpga_data); + return 0; +} + +#ifdef TEST_MODE + #define FPGA_PCI_BAR_NUM 2 +#else + #define FPGA_PCI_BAR_NUM 0 +#endif + + + +static const struct pci_device_id fpga_id_table[] = { + { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, + { PCI_VDEVICE(TEST, TEST_PCIE_DEVICE_ID) }, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, fpga_id_table); + +static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) +{ + int err; + struct device *dev = &pdev->dev; + if ((err = pci_enable_device(pdev))) { + dev_err(dev, "pci_enable_device probe error %d for device %s\n", + err, pci_name(pdev)); + return err; + } + + if ((err = pci_request_regions(pdev, FPGA_PCI_NAME)) < 0) { + dev_err(dev, "pci_request_regions error %d\n", err); + goto pci_disable; + } + + /* bar0: data mmio region */ + fpga_dev.data_mmio_start = pci_resource_start(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_mmio_len = pci_resource_len(pdev, FPGA_PCI_BAR_NUM); + fpga_dev.data_base_addr = pci_iomap(pdev, FPGA_PCI_BAR_NUM, 0); + if (!fpga_dev.data_base_addr) { + dev_err(dev, "cannot iomap region of size %lu\n", + (unsigned long)fpga_dev.data_mmio_len); + goto pci_release; + } + dev_info(dev, "data_mmio iomap base = 0x%lx \n", + (unsigned long)fpga_dev.data_base_addr); + dev_info(dev, "data_mmio_start = 0x%lx data_mmio_len = %lu\n", + (unsigned long)fpga_dev.data_mmio_start, + (unsigned long)fpga_dev.data_mmio_len); + + printk(KERN_INFO "FPGA PCIe driver probe OK.\n"); + printk(KERN_INFO "FPGA ioremap registers of size %lu\n",(unsigned long)fpga_dev.data_mmio_len); + printk(KERN_INFO "FPGA Virtual BAR %d at %8.8lx - %8.8lx\n",FPGA_PCI_BAR_NUM,(unsigned long)fpga_dev.data_base_addr,(unsigned long)fpga_dev.data_base_addr+ (unsigned long)fpga_dev.data_mmio_len); + printk(KERN_INFO ""); + uint32_t buff = ioread32(fpga_dev.data_base_addr); + printk(KERN_INFO "FPGA VERSION : %8.8x\n", buff); + fpgafw_init(); + return 0; + +reg_release: + pci_iounmap(pdev, fpga_dev.data_base_addr); +pci_release: + pci_release_regions(pdev); +pci_disable: + pci_disable_device(pdev); + return -EBUSY; +} + +static void fpga_pci_remove(struct pci_dev *pdev) +{ + fpgafw_exit(); + pci_iounmap(pdev, fpga_dev.data_base_addr); + pci_release_regions(pdev); + pci_disable_device(pdev); + printk(KERN_INFO "FPGA PCIe driver remove OK.\n"); +}; + +static struct pci_driver pci_dev_ops = { + .name = FPGA_PCI_NAME, + .probe = fpga_pci_probe, + .remove = fpga_pci_remove, + .id_table = fpga_id_table, +}; + + +static struct platform_driver seastone2_drv = { + .probe = seastone2_drv_probe, + .remove = __exit_p(seastone2_drv_remove), + .driver = { + .name = DRIVER_NAME, + }, +}; + +enum{ + READREG, + WRITEREG +}; + +struct fpga_reg_data { + uint32_t addr; + uint32_t value; +}; + +static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg){ + int ret = 0; + struct fpga_reg_data data; + mutex_lock(&fpga_data->fpga_lock); + +#ifdef TEST_MODE + static uint32_t status_reg; +#endif + // Switch function to read and write. + switch (cmd){ + case READREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0){ + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + data.value = ioread32(fpga_dev.data_base_addr+data.addr); + if (copy_to_user((void __user*)arg ,&data, sizeof(data)) != 0){ + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } +#ifdef TEST_MODE + if(data.addr == 0x1210){ + switch (status_reg){ + case 0x0000 : status_reg=0x8000; + break; + + case 0x8080 : status_reg=0x80C0; + break; + case 0x80C0 : status_reg=0x80F0; + break; + case 0x80F0 : status_reg=0x80F8; + break; + + } + iowrite32(status_reg,fpga_dev.data_base_addr+0x1210); + } +#endif + + + break; + case WRITEREG: + if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0){ + mutex_unlock(&fpga_data->fpga_lock); + return -EFAULT; + } + iowrite32(data.value,fpga_dev.data_base_addr+data.addr); + +#ifdef TEST_MODE + if(data.addr == 0x1204){ + status_reg=0x8080; + iowrite32(status_reg,fpga_dev.data_base_addr+0x1210); + } +#endif + + break; + default: + mutex_unlock(&fpga_data->fpga_lock); + return -EINVAL; + } + mutex_unlock(&fpga_data->fpga_lock); + return ret; +} + + +const struct file_operations fpgafw_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = fpgafw_unlocked_ioctl, +}; + + +static int fpgafw_init(void){ + printk(KERN_INFO "Initializing the switchboard driver\n"); + // Try to dynamically allocate a major number for the device -- more difficult but worth it + majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); + if (majorNumber<0){ + printk(KERN_ALERT "Failed to register a major number\n"); + return majorNumber; + } + printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); + + // Register the device class + fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); + if (IS_ERR(fpgafwclass)){ // Check for error and clean up if there is + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to register device class\n"); + return PTR_ERR(fpgafwclass); // Correct way to return an error on a pointer + } + printk(KERN_INFO "Device class registered correctly\n"); + + // Register the device driver + fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); + if (IS_ERR(fpgafwdev)){ // Clean up if there is an error + class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements + unregister_chrdev(majorNumber, DEVICE_NAME); + printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); + return PTR_ERR(fpgafwdev); + } + printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); // Made it! device was initialized + return 0; +} + +static void fpgafw_exit(void){ + device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device + class_unregister(fpgafwclass); // unregister the device class + class_destroy(fpgafwclass); // remove the device class + unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number + printk(KERN_INFO "Goodbye!\n"); +} + +int seastone2_init(void) +{ + int rc; + rc = pci_register_driver(&pci_dev_ops); + if (rc) + return rc; + if(fpga_dev.data_base_addr == NULL){ + printk(KERN_ALERT "FPGA PCIe device not found!\n"); + return -ENODEV; + } + platform_device_register(&seastone2_dev); + platform_driver_register(&seastone2_drv); + return 0; +} + +void seastone2_exit(void) +{ + platform_driver_unregister(&seastone2_drv); + platform_device_unregister(&seastone2_dev); + pci_unregister_driver(&pci_dev_ops); +} + +module_init(seastone2_init); +module_exit(seastone2_exit); + +MODULE_AUTHOR("Pradchaya P. pphuhcar@celestica.com"); +#ifdef SEASTONE2 +MODULE_DESCRIPTION("Celestica seastone2 platform driver"); +#else +MODULE_DESCRIPTION("Celestica questone2 platform driver"); +#endif +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff-8436.h b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff-8436.h new file mode 100644 index 0000000000..3f8f00f4dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff-8436.h @@ -0,0 +1,31 @@ +#ifndef _LINUX_SFF_8436_H +#define _LINUX_SFF_8436_H + +#include +#include + +/* + * As seen through Linux I2C, differences between the most common types of I2C + * memory include: + * - How much memory is available (usually specified in bit)? + * - What write page size does it support? + * - Special flags (read_only, world readable...)? + * + * If you set up a custom eeprom type, please double-check the parameters. + * Especially page_size needs extra care, as you risk data loss if your value + * is bigger than what the chip actually supports! + */ + +struct sff_8436_platform_data { + u32 byte_len; /* size (sum of all addr) */ + u16 page_size; /* for writes */ + u8 flags; +#define SFF_8436_FLAG_READONLY 0x40 /* sysfs-entry will be read-only */ +#define SFF_8436_FLAG_IRUGO 0x20 /* sysfs-entry will be world-readable */ +#define SFF_8436_FLAG_TAKE8ADDR 0x10 /* take always 8 addresses (24c00) */ + + //void (*setup)(struct memory_accessor *, void *context); + //void *context; +}; + +#endif /* _LINUX_SFF_8436_H */ diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff_8436_eeprom.c b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff_8436_eeprom.c new file mode 100644 index 0000000000..6779ccee5e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff_8436_eeprom.c @@ -0,0 +1,982 @@ +/* + * sff_8436_eeprom.c - handle most SFF-8436 based QSFP EEPROMs + * + * Copyright (C) 2014 Cumulus networks Inc. + * + * 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 + * the Freeoftware Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +/* + * Description: + * a) SFF 8436 based qsfp read/write transactions are just like the at24 eeproms + * b) The register/memory layout is up to 5 128 byte pages defined by a "pages valid" + * register and switched via a "page select" register as explained in below diagram. + * c) 256 bytes are mapped at a time. page 0 is always mapped to the first 128 bytes and + * the other 4 pages are selectively mapped to the second 128 bytes + * + * SFF 8436 based QSFP Memory Map + * + * 2-Wire Serial Address: 1010000x + * + * Lower Page 00h (128 bytes) + * ===================== + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * | | + * |Page Select Byte(127)| + * ===================== + * | + * | + * | + * | + * V + * ----------------------------------------------------------------- + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * | | | | + * V V V V + * ------------- ---------------- ----------------- -------------- + * | | | | | | | | + * | Upper | | Upper | | Upper | | Upper | + * | Page 00h | | Page 01h | | Page 02h | | Page 03h | + * | | | (Optional) | | (Optional) | | (Optional | + * | | | | | | | for Cable | + * | | | | | | | Assemblies) | + * | ID | | AST | | User | | | + * | Fields | | Table | | EEPROM Data | | | + * | | | | | | | | + * | | | | | | | | + * | | | | | | | | + * ------------- ---------------- ----------------- -------------- + * + * + **/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "sff-8436.h" + +#include +#include + +#define SFF_8436_EEPROM_SIZE 5*128 +#define SFF_8436_MAX_PAGE_COUNT 5 +#define SFF_8436_MMAP_SIZE 256 +#define SFF_8436_PAGE_SELECT_REG 0x7F + +#define SFF_8436_OPTION_4_OFFSET 0xC3 +#define SFF_8436_PAGE_02_PRESENT (1 << 7) /* Memory Page 02 present */ +#define SFF_8436_PAGE_01_PRESENT (1 << 6) /* Memory Page 01 present */ +#define SFF_8436_STATUS_2_OFFSET 0x02 +#define SFF_8436_STATUS_PAGE_03_PRESENT_L (1 << 2) /* Flat Memory:0- Paging, 1- Page 0 only */ + +struct sff_8436_data { + struct sff_8436_platform_data chip; + //struct memory_accessor macc; + int use_smbus; + + /* + * Lock protects against activities from other Linux tasks, + * but not from changes by other I2C masters. + */ + struct mutex lock; + struct bin_attribute bin; + + u8 *writebuf; + unsigned write_max; + + unsigned num_addresses; + + u8 data[SFF_8436_EEPROM_SIZE]; + + struct i2c_client *client[]; +}; + +typedef enum qsfp_opcode { + QSFP_READ_OP = 0, + QSFP_WRITE_OP = 1 +} qsfp_opcode_e; + +/* + * This parameter is to help this driver avoid blocking other drivers out + * of I2C for potentially troublesome amounts of time. With a 100 kHz I2C + * clock, one 256 byte read takes about 1/43 second which is excessive; + * but the 1/170 second it takes at 400 kHz may be quite reasonable; and + * at 1 MHz (Fm+) a 1/430 second delay could easily be invisible. + * + * This value is forced to be a power of two so that writes align on pages. + */ +static unsigned io_limit = 128; + +/* + *pecs often allow 5 msec for a page write, sometimes 20 msec; + * it's important to recover from write timeouts. + */ +static unsigned write_timeout = 25; + +#define SFF_8436_PAGE_SIZE 128 +#define SFF_8436_SIZE_BYTELEN 5 +#define SFF_8436_SIZE_FLAGS 8 + +#define SFF_8436_BITMASK(x) (BIT(x) - 1) + + +/* create non-zero magic value for given eeprom parameters */ +#define SFF_8436_DEVICE_MAGIC(_len, _flags) \ + ((1 << SFF_8436_SIZE_FLAGS | (_flags)) \ + << SFF_8436_SIZE_BYTELEN | ilog2(_len)) + +static const struct i2c_device_id sff8436_ids[] = { + { "sff8436",SFF_8436_DEVICE_MAGIC(2048 / 8, 0) }, + { /* END OF LIST */ } +}; +MODULE_DEVICE_TABLE(i2c, sff8436_ids); + +/*-------------------------------------------------------------------------*/ +/* + * This routine computes the addressing information to be used for a given r/w request. + * Assumes that sanity checks for offset happened at sysfs-layer. + * Offset within Lower Page 00h and Upper Page 00h are not recomputed + */ +static uint8_t sff_8436_translate_offset(struct sff_8436_data *sff_8436, + loff_t *offset) +{ + unsigned page = 0; + + if (*offset < SFF_8436_MMAP_SIZE) { + return 0; + } + + page = (*offset >> 7)-1; + + if (page > 0 ) { + *offset = 0x80 + (*offset & 0x7f); + } else { + *offset &= 0xff; + } + + return page; +} + +static int sff_8436_read_reg(struct sff_8436_data *sff_8436, + uint8_t reg, uint8_t *val) +{ + int count = 1, i = 0; + struct i2c_client *client = sff_8436->client[0]; + struct i2c_msg msg[2]; + u8 msgbuf[2]; + ssize_t status; + unsigned long timeout, read_time; + + memset(msg, 0, sizeof(msg)); + + /* + * Writes fail if the previous one didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + switch (sff_8436->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_read_i2c_block_data(client, + reg, count, val); + break; + case I2C_SMBUS_WORD_DATA: + status = i2c_smbus_read_word_data(client, reg); + + if (status >= 0) { + *val = status & 0xff; + status = count; + } + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_read_byte_data(client, reg); + + if (status >= 0) { + *val = status; + status = count; + } + break; + + default: + i = 0; + msgbuf[i++] = reg; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = val; + msg[1].len = count; + + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + status = count; + break; + } + dev_dbg(&client->dev, "read (using smbus %d) %d@%d --> %zd (%ld)\n", + sff_8436->use_smbus, count, reg, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static int sff_8436_write_reg(struct sff_8436_data *sff_8436, + uint8_t reg, uint8_t val) +{ + uint8_t data[2] = { reg, val }; + int count = 1; + struct i2c_client *client = sff_8436->client[0]; + struct i2c_msg msg; + ssize_t status; + unsigned long timeout, write_time; + + /* + * Writes fail if the previous one didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + switch (sff_8436->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_write_i2c_block_data(client, + reg, count, &val); + if (status == 0) + status = count; + break; + case I2C_SMBUS_WORD_DATA: + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_write_byte_data(client, reg, val); + + if (status == 0) + status = count; + break; + default: + msg.addr = client->addr; + msg.flags = 0; + msg.len = sizeof(data); + msg.buf = (char *) data; + + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + break; + } + dev_dbg(&client->dev, "write (using smbus %d) %d@%d --> %zd (%ld)\n", + sff_8436->use_smbus, count, reg, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + +static int sff_8436_write_page_reg(struct sff_8436_data *sff_8436, + uint8_t val) +{ + return sff_8436_write_reg(sff_8436, SFF_8436_PAGE_SELECT_REG, val); +} + +static ssize_t sff_8436_eeprom_read(struct sff_8436_data *sff_8436, char *buf, + unsigned offset, size_t count) +{ + struct i2c_msg msg[2]; + u8 msgbuf[2]; + struct i2c_client *client = sff_8436->client[0]; + unsigned long timeout, read_time; + int status, i; + + memset(msg, 0, sizeof(msg)); + + switch (sff_8436->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* + * When we have a better choice than SMBus calls, use a + * combined I2C message. Write address; then read up to + * io_limit data bytes. Note that read page rollover helps us + * here (unlike writes). msgbuf is u8 and will cast to our + * needs. + */ + i = 0; + msgbuf[i++] = offset; + + msg[0].addr = client->addr; + msg[0].buf = msgbuf; + msg[0].len = i; + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + read_time = jiffies; + + switch (sff_8436->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_read_i2c_block_data(client, offset, + count, buf); + break; + case I2C_SMBUS_WORD_DATA: + status = i2c_smbus_read_word_data(client, offset); + if (status >= 0) { + buf[0] = status & 0xff; + if (count == 2) + buf[1] = status >> 8; + status = count; + } + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_read_byte_data(client, offset); + if (status >= 0) { + buf[0] = status; + status = count; + } + break; + default: + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + status = count; + } + + dev_dbg(&client->dev, "eeprom read %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(read_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t sff_8436_eeprom_write(struct sff_8436_data *sff_8436, const char *buf, + unsigned offset, size_t count) +{ + struct i2c_client *client = sff_8436->client[0]; + struct i2c_msg msg; + unsigned long timeout, write_time; + unsigned next_page; + int status, i = 0; + + /* write max is at most a page */ + if (count > sff_8436->write_max) + count = sff_8436->write_max; + + /* Never roll over backwards, to the start of this page */ + next_page = roundup(offset + 1, SFF_8436_PAGE_SIZE); + if (offset + count > next_page) + count = next_page - offset; + + switch (sff_8436->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + /*smaller eeproms can work given some SMBus extension calls */ + if (count > I2C_SMBUS_BLOCK_MAX) + count = I2C_SMBUS_BLOCK_MAX; + break; + case I2C_SMBUS_WORD_DATA: + /* Check for odd length transaction */ + count = (count == 1) ? 1 : 2; + break; + case I2C_SMBUS_BYTE_DATA: + count = 1; + break; + default: + /* If we'll use I2C calls for I/O, set up the message */ + msg.addr = client->addr; + msg.flags = 0; + + /* msg.buf is u8 and casts will mask the values */ + msg.buf = sff_8436->writebuf; + + msg.buf[i++] = offset; + memcpy(&msg.buf[i], buf, count); + msg.len = i + count; + break; + } + + /* + * Reads fail if the previous write didn't complete yet. We may + * loop a few times until this one succeeds, waiting at least + * long enough for one entire page write to work. + */ + timeout = jiffies + msecs_to_jiffies(write_timeout); + do { + write_time = jiffies; + + switch (sff_8436->use_smbus) { + case I2C_SMBUS_I2C_BLOCK_DATA: + status = i2c_smbus_write_i2c_block_data(client, + offset, count, buf); + if (status == 0) + status = count; + break; + case I2C_SMBUS_WORD_DATA: + if (count == 2) { + status = i2c_smbus_write_word_data( + client,offset,(u16)((buf[0]) | + (buf[1] << 8))); + } else { + /* count = 1 */ + status = i2c_smbus_write_byte_data( + client, offset, buf[0]); + } + if (status == 0) + status = count; + break; + case I2C_SMBUS_BYTE_DATA: + status = i2c_smbus_write_byte_data(client, offset, buf[0]); + if (status == 0) + status = count; + break; + default: + status = i2c_transfer(client->adapter, &msg, 1); + if (status == 1) + status = count; + break; + } + + dev_dbg(&client->dev, "eeprom write %zu@%d --> %d (%ld)\n", + count, offset, status, jiffies); + + if (status == count) + return count; + + /* REVISIT: at HZ=100, this is sloooow */ + msleep(1); + } while (time_before(write_time, timeout)); + + return -ETIMEDOUT; +} + +static ssize_t sff_8436_eeprom_update_client(struct sff_8436_data *sff_8436, + loff_t off, size_t count, qsfp_opcode_e opcode) +{ + struct i2c_client *client = sff_8436->client[0]; + ssize_t retval = 0; + u8 page = 0; + loff_t phy_offset = off; + int ret = 0; + + page = sff_8436_translate_offset(sff_8436, &phy_offset); + + dev_dbg(&client->dev, + "sff_8436_eeprom_update_client off %lld page:%d phy_offset:%lld, count:%zu, opcode:%d\n", + off, page, phy_offset, count, opcode); + if (page > 0) { + ret = sff_8436_write_page_reg(sff_8436, page); + if (ret < 0) { + dev_err(&client->dev, + "sff_8436_write_page_reg for page %d failed ret:%d!\n", + page, ret); + return ret; + } + } + + while (count) { + ssize_t status; + + if (opcode == QSFP_READ_OP) { + status = sff_8436_eeprom_read(sff_8436, (char *)(&sff_8436->data[off]), phy_offset, count); + } else { + status = sff_8436_eeprom_write(sff_8436, (char *)(&sff_8436->data[off]), phy_offset, count); + } + if (status <= 0) { + if (retval == 0) + retval = status; + break; + } + phy_offset += status; + off += status; + count -= status; + retval += status; + } + + + if (page > 0) { + ret = sff_8436_write_page_reg(sff_8436, 0); + if (ret < 0) { + dev_err(&client->dev, + "sff_8436_write_page_reg for page 0 failed ret:%d!\n", ret); + return ret; + } + } + return retval; +} + +static ssize_t sff_8436_read_write(struct sff_8436_data *sff_8436, + char *buf, loff_t off, size_t len, qsfp_opcode_e opcode) +{ + struct i2c_client *client = sff_8436->client[0]; + u8 page; + u8 refresh_page = 0; + int ret = 0; + u8 val = 0; + int err_timeout = 0; + size_t pending_len = 0, page_len = 0; + loff_t page_offset = 0, page_start_offset = 0; + + if (unlikely(!len)) + return len; + + if (off > SFF_8436_EEPROM_SIZE) + return 0; + + if (off + len > SFF_8436_EEPROM_SIZE) + len = SFF_8436_EEPROM_SIZE - off; + + if (opcode == QSFP_READ_OP) { + memset(sff_8436->data, 0xff, SFF_8436_EEPROM_SIZE); + } else if (opcode == QSFP_WRITE_OP) { + memcpy(&sff_8436->data[off], buf, len); + } + + /* + * Read data from chip, protecting against concurrent updates + * from this host, but not from other I2C masters. + */ + mutex_lock(&sff_8436->lock); + + /* + * Refresh pages which covers the requested data + * from offset to off + len + * Only refresh pages which contain requested bytes + * + */ + + pending_len = len; + + for (page = off >> 7; page <= (off + len - 1) >> 7; page++) { + refresh_page = 0; + switch (page) { + case 0: + /* Lower page 00h */ + refresh_page = 1; + err_timeout = 1; + break; + case 1: + /* Upper page 00h */ + refresh_page = 1; + err_timeout = 1; + break; + case 2: + /* Upper page 01h */ + ret = sff_8436_read_reg(sff_8436, SFF_8436_OPTION_4_OFFSET, &val); + if (ret < 0) { + dev_dbg(&client->dev, + "sff_8436_read_reg for page 01h status failed %d!\n", ret); + goto err; + } + if (val & SFF_8436_PAGE_01_PRESENT) { + refresh_page = 1; + } + break; + case 3: + /* Upper page 02h */ + ret = sff_8436_read_reg(sff_8436, SFF_8436_OPTION_4_OFFSET, &val); + if (ret < 0) { + dev_dbg(&client->dev, + "sff_8436_read_reg for page 02h status failed %d!\n", ret); + goto err; + } + if (val & SFF_8436_PAGE_02_PRESENT) { + refresh_page = 1; + } + break; + case 4: + /* Upper page 03h */ + ret = sff_8436_read_reg(sff_8436, SFF_8436_STATUS_2_OFFSET, &val); + if (ret < 0) { + dev_dbg(&client->dev, + "sff_8436_read_reg for page 03h status failed %d!\n", ret); + goto err; + } + if (!(val & SFF_8436_STATUS_PAGE_03_PRESENT_L)) { + refresh_page = 1; + } + break; + default: + /* Invalid page index */ + dev_err(&client->dev, "Invalid page %d!\n", page); + ret = -EINVAL; + goto err; + } + + if (!refresh_page) { + /* if page is not valid or already refreshed */ + continue; + } + + /* + * Compute the offset and number of bytes to be read/write + * w.r.t requested page + * + * 1. start at offset 0 (within the page), and read/write the entire page + * 2. start at offset 0 (within the page) and read/write less than entire page + * 3. start at an offset not equal to 0 and read/write the rest of the page + * 4. start at an offset not equal to 0 and read/write less than (end of page - offset) + * + */ + page_start_offset = page * SFF_8436_PAGE_SIZE; + + if (page_start_offset < off) { + page_offset = off; + if (off + pending_len < page_start_offset + SFF_8436_PAGE_SIZE) { + page_len = pending_len; + } else { + page_len = SFF_8436_PAGE_SIZE - off; + } + } else { + page_offset = page_start_offset; + if (pending_len > SFF_8436_PAGE_SIZE) { + page_len = SFF_8436_PAGE_SIZE; + } else { + page_len = pending_len; + } + } + + pending_len = pending_len - page_len; + + dev_dbg(&client->dev, + "sff_read off %lld len %zu page_start_offset %lld page_offset %lld page_len %zu pending_len %zu\n", + off, len, page_start_offset, page_offset, page_len, pending_len); + + /* Refresh the data from offset for specified len */ + ret = sff_8436_eeprom_update_client(sff_8436, page_offset, page_len, opcode); + if (ret != page_len) { + if (err_timeout) { + dev_dbg(&client->dev, "sff_8436_update_client for %s page %d page_offset %lld page_len %zu failed %d!\n", + (page ? "Upper" : "Lower"), (page ? (page-1) : page), page_offset, page_len, ret); + goto err; + } else { + dev_err(&client->dev, "sff_8436_update_client for %s page %d page_offset %lld page_len %zu failed %d!\n", + (page ? "Upper" : "Lower"), (page ? (page-1) : page), page_offset, page_len, ret); + } + } + } + mutex_unlock(&sff_8436->lock); + + if (opcode == QSFP_READ_OP) { + memcpy(buf, &sff_8436->data[off], len); + } + return len; + +err: + mutex_unlock(&sff_8436->lock); + + return ret; +} + +static ssize_t sff_8436_bin_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct sff_8436_data *sff_8436 = i2c_get_clientdata(client); + + return sff_8436_read_write(sff_8436, buf, off, count, QSFP_READ_OP); +} + + +static ssize_t sff_8436_bin_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct i2c_client *client = to_i2c_client(container_of(kobj, struct device, kobj)); + struct sff_8436_data *sff_8436 = i2c_get_clientdata(client); + + return sff_8436_read_write(sff_8436, buf, off, count, QSFP_WRITE_OP); +} +/*-------------------------------------------------------------------------*/ + +/* + * This lets other kernel code access the eeprom data. For example, it + * might hold a board's Ethernet address, or board-specific calibration + * data generated on the manufacturing floor. + */ + +// static ssize_t sff_8436_macc_read(struct memory_accessor *macc, char *buf, +// off_t offset, size_t count) +// { +// struct sff_8436_data *sff_8436 = container_of(macc, struct sff_8436_data, macc); + +// return sff_8436_read_write(sff_8436, buf, offset, count, QSFP_READ_OP); +// } + +// static ssize_t sff_8436_macc_write(struct memory_accessor *macc, const char *buf, +// off_t offset, size_t count) +// { +// struct sff_8436_data *sff_8436 = container_of(macc, struct sff_8436_data, macc); + +// return sff_8436_read_write(sff_8436, buf, offset, count, QSFP_WRITE_OP); +// } + +/*-------------------------------------------------------------------------*/ + +static int sff_8436_remove(struct i2c_client *client) +{ + struct sff_8436_data *sff_8436; + + sff_8436 = i2c_get_clientdata(client); + sysfs_remove_bin_file(&client->dev.kobj, &sff_8436->bin); + + kfree(sff_8436->writebuf); + kfree(sff_8436); + return 0; +} +static int sff_8436_eeprom_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err; + int use_smbus = 0; + struct sff_8436_platform_data chip; + struct sff_8436_data *sff_8436; + kernel_ulong_t magic; + + if (client->dev.platform_data) { + chip = *(struct sff_8436_platform_data *)client->dev.platform_data; + } else { + /* + * SFF-8436 MMAP is 256 bytes long + */ + magic = SFF_8436_DEVICE_MAGIC(2048 / 8, 0); + chip.byte_len = BIT(magic & SFF_8436_BITMASK(SFF_8436_SIZE_BYTELEN)); + magic >>= SFF_8436_SIZE_BYTELEN; + chip.flags = magic & SFF_8436_BITMASK(SFF_8436_SIZE_FLAGS); + /* + * This is slow, but we can't know all eeproms, so we better + * play safe.pecifying custom eeprom-types via platform_data + * is recommended anyhow. + */ + chip.page_size = 1; + + //chip.setup = NULL; + //chip.context = NULL; + } + + if (!is_power_of_2(chip.byte_len)) + dev_warn(&client->dev, + "byte_len looks suspicious (no power of 2)!\n"); + + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + err = -EINVAL; + goto exit; + } + if (!is_power_of_2(chip.page_size)) + dev_warn(&client->dev, + "page_size looks suspicious (no power of 2)!\n"); + + /* Use I2C operations unless we're stuck with SMBus extensions. */ + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_I2C_BLOCK)) { + use_smbus = I2C_SMBUS_I2C_BLOCK_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_WORD_DATA)) { + use_smbus = I2C_SMBUS_WORD_DATA; + } else if (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_READ_BYTE_DATA)) { + use_smbus = I2C_SMBUS_BYTE_DATA; + } else { + err = -EPFNOSUPPORT; + goto exit; + } + } + + if (!(sff_8436 = kzalloc(sizeof(struct sff_8436_data) + sizeof(struct i2c_client *), GFP_KERNEL))) { + err = -ENOMEM; + goto exit; + } + + mutex_init(&sff_8436->lock); + sff_8436->use_smbus = use_smbus; + sff_8436->chip = chip; + + /* + * Export the EEPROM bytes through sysfs, since that's convenient. + * By default, only root should see the data (maybe passwords etc) + */ + sysfs_bin_attr_init(&sff_8436->bin); + sff_8436->bin.attr.name = "eeprom"; + sff_8436->bin.attr.mode = SFF_8436_FLAG_IRUGO; + sff_8436->bin.read = sff_8436_bin_read; + sff_8436->bin.size = SFF_8436_EEPROM_SIZE; + + //sff_8436->macc.read = sff_8436_macc_read; + + if (!use_smbus || + (i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_I2C_BLOCK)) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_WORD_DATA) || + i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_WRITE_BYTE_DATA)) { + //unsigned write_max = chip.page_size; + /* + * NOTE: AN-2079 + * Finisar recommends that the host implement 1 byte writes only, + * since this module only supports 32 byte page boundaries. + * 2 byte writes are acceptable for PE and Vout changes per + * Application Note AN-2071. + */ + unsigned write_max = 1; + + //sff_8436->macc.write = sff_8436_macc_write; + + sff_8436->bin.write = sff_8436_bin_write; + sff_8436->bin.attr.mode |= S_IWUSR; + + if (write_max > io_limit) + write_max = io_limit; + if (use_smbus && write_max > I2C_SMBUS_BLOCK_MAX) + write_max = I2C_SMBUS_BLOCK_MAX; + sff_8436->write_max = write_max; + + /* buffer (data + address at the beginning) */ + sff_8436->writebuf = kmalloc(write_max + 2, GFP_KERNEL); + if (!sff_8436->writebuf) { + err = -ENOMEM; + goto exit_kfree; + } + } else { + dev_warn(&client->dev, + "cannot write due to controller restrictions."); + } + + memset(sff_8436->data, 0xff, SFF_8436_EEPROM_SIZE); + + sff_8436->client[0] = client; + + /* create the sysfs eeprom file */ + err = sysfs_create_bin_file(&client->dev.kobj, &sff_8436->bin); + if (err) + goto err_struct; + + i2c_set_clientdata(client, sff_8436); + + dev_info(&client->dev, "%zu byte %s EEPROM, %s\n", + sff_8436->bin.size, client->name, + "read-only"); + + if (use_smbus == I2C_SMBUS_WORD_DATA || + use_smbus == I2C_SMBUS_BYTE_DATA) { + dev_notice(&client->dev, "Falling back to %s reads, " + "performance will suffer\n", use_smbus == + I2C_SMBUS_WORD_DATA ? "word" : "byte"); + } + + //if (chip.setup) + //chip.setup(&sff_8436->macc, chip.context); + + return 0; + +err_sysfs_cleanup: + sysfs_remove_bin_file(&client->dev.kobj, &sff_8436->bin); +err_struct: + kfree(sff_8436->writebuf); +exit_kfree: + kfree(sff_8436); +exit: + dev_dbg(&client->dev, "probe error %d\n", err); + + return err; +} + +/*-------------------------------------------------------------------------*/ + +static struct i2c_driver sff_8436_driver = { + .driver = { + .name = "sff8436", + .owner = THIS_MODULE, + }, + .probe = sff_8436_eeprom_probe, + .remove = sff_8436_remove, + .id_table = sff8436_ids, +}; + +static int __init sff_8436_init(void) +{ + if (!io_limit) { + pr_err("sff_8436: io_limit must not be 0!\n"); + return -EINVAL; + } + + io_limit = rounddown_pow_of_two(io_limit); + return i2c_add_driver(&sff_8436_driver); +} +module_init(sff_8436_init); + +static void __exit sff_8436_exit(void) +{ + i2c_del_driver(&sff_8436_driver); +} +module_exit(sff_8436_exit); + +MODULE_DESCRIPTION("Driver for SFF-8436 based QSFP EEPROMs"); +MODULE_AUTHOR("VIDYA RAVIPATI "); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/platform_sensors.py new file mode 100755 index 0000000000..b600d48e8f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/platform_sensors.py @@ -0,0 +1,161 @@ +#!/usr/bin/python +# +# Silverstone platform sensors. This script get the sensor data from BMC +# using ipmitool and display them in lm-sensor alike format. +# +# The following data is support: +# 1. Temperature sensors +# 2. PSUs +# 3. Fan Drawers + +import sys +import logging +import subprocess + +IPMI_SDR_CMD = ['/usr/bin/ipmitool', 'sdr', 'elist'] +MAX_NUM_FANS = 4 +MAX_NUM_PSUS = 2 + +SENSOR_NAME = 0 +SENSOR_VAL = 4 + +sensor_dict = {} + +def ipmi_sensor_dump(cmd): + ''' Execute ipmitool command return dump output + exit if any error occur. + ''' + global sensor_dict + sensor_dump = '' + + try: + sensor_dump = subprocess.check_output(IPMI_SDR_CMD, universal_newlines=True) + except subprocess.CalledProcessError as e: + logging.error('Error! Failed to execute: {}'.format(cmd)) + sys.exit(1) + + for line in sensor_dump.splitlines(): + sensor_info = line.split('|') + sensor_dict[sensor_info[SENSOR_NAME].strip()] = sensor_info[SENSOR_VAL].strip() + + return True + +def get_reading_by_name(sensor_name, sdr_elist_dump): + found = '' + + for line in sdr_elist_dump.splitlines(): + line = line.decode() + if sensor_name in line: + found = line.strip() + break + + if not found: + logging.error('Cannot find sensor name:' + sensor_name) + + else: + try: + found = found.split('|')[4] + except IndexError: + logging.error('Cannot get sensor data of:' + sensor_name) + + logging.basicConfig(level=logging.DEBUG) + return found + + +def read_temperature_sensors(): + sensor_list = [\ + ('Base_Temp_U5', 'Baseboard Right Temp'),\ + ('Base_Temp_U7', 'Baseboard Left Temp'),\ + ('Switch_Temp_U31', 'ASIC External Front Temp'),\ + ('Switch_Temp_U30', 'ASIC External Rear Temp'),\ + ('Switch_Temp_U29', 'Switchboard Right Temp'),\ + ('Switch_Temp_U28', 'Switchboard Left Temp'),\ + ('CPU_Temp', 'CPU Internal Temp'),\ + ('Switch_U33_Temp', 'IR3595 Chip Temp'),\ + ('Switch_U21_Temp', 'IR3584 Chip Temp'),\ + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "Temperature Sensors\n" + output += "Adapter: IPMI adapter\n" + for sensor in sensor_list: + output += sensor_format.format('{}:'.format(sensor[1]),\ + sensor_dict[sensor[0]],\ + width=str(max_name_width+1)) + output += '\n' + return output + +def read_fan_sensors(num_fans): + + sensor_list = [\ + ('Fan{}_Status', 'Fan Drawer {} Status'),\ + ('Fan{}_Front', 'Fan {} front'),\ + ('Fan{}_Rear', 'Fan {} rear'),\ + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "Fan Drawers\n" + output += "Adapter: IPMI adapter\n" + for fan_num in range(1, num_fans+1): + for sensor in sensor_list: + ipmi_sensor_name = sensor[0].format(fan_num) + display_sensor_name = sensor[1].format(fan_num) + output += sensor_format.format('{}:'.format(display_sensor_name),\ + sensor_dict[ipmi_sensor_name],\ + width=str(max_name_width+1)) + output += '\n' + return output + +def read_psu_sensors(num_psus): + + sensor_list = [\ + ('PSU{}_Status', 'PSU {} Status'),\ + ('PSU{}_Fan', 'PSU {} Fan 1'),\ + ('PSU{}_VIn', 'PSU {} Input Voltage'),\ + ('PSU{}_CIn', 'PSU {} Input Current'),\ + ('PSU{}_PIn', 'PSU {} Input Power'),\ + ('PSU{}_Temp1', 'PSU {} Ambient Temp'),\ + ('PSU{}_Temp2', 'PSU {} Hotspot Temp'),\ + ('PSU{}_VOut', 'PSU {} Output Voltage'),\ + ('PSU{}_COut', 'PSU {} Output Current'),\ + ('PSU{}_POut', 'PSU {} Output Power'),\ + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "PSU\n" + output += "Adapter: IPMI adapter\n" + for psu_num in range(1, num_psus+1): + for sensor in sensor_list: + ipmi_sensor_name = sensor[0].format('L' if psu_num == 1 else 'R') + display_sensor_name = sensor[1].format(psu_num) + output += sensor_format.format('{}:'.format(display_sensor_name),\ + sensor_dict[ipmi_sensor_name],\ + width=str(max_name_width+1)) + output += '\n' + return output + +def main(): + output_string = '' + + if ipmi_sensor_dump(IPMI_SDR_CMD): + output_string += read_temperature_sensors() + output_string += read_psu_sensors(MAX_NUM_PSUS) + output_string += read_fan_sensors(MAX_NUM_FANS) + + print(output_string) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/questone2_platform_shutdown.sh b/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/questone2_platform_shutdown.sh new file mode 100755 index 0000000000..e04cac54fa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/questone2_platform_shutdown.sh @@ -0,0 +1,26 @@ +#!/bin/bash +REBOOT_CAUSE_DIR="/host/reboot-cause" +HW_REBOOT_CAUSE_FILE="/host/reboot-cause/hw-reboot-cause.txt" +REBOOT_TIME=$(date) + +if [ $# -ne 1 ]; then + echo "Require reboot type" + exit 1 +fi + +if [ ! -d "$REBOOT_CAUSE_DIR" ]; then + mkdir $REBOOT_CAUSE_DIR +fi + +echo "Reason:$1,Time:${REBOOT_TIME}" > ${HW_REBOOT_CAUSE_FILE} + +# Best effort to write buffered data onto the disk +sync ; sync ; sync ; sleep 3 + +# BMC cold power-cyle +ipmitool chassis power cycle &> /dev/null + +# System should reboot by now and avoid the script returning to caller +sleep 10 + +exit 0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/sensors b/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/sensors new file mode 100755 index 0000000000..5d740a9eb7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/scripts/sensors @@ -0,0 +1,11 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS pmon sensors "$@" +docker exec -$DOCKER_EXEC_FLAGS pmon python3 /usr/bin/platform_sensors.py "$@" diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/setup.py b/platform/broadcom/sonic-platform-modules-cel/questone2/setup.py new file mode 100644 index 0000000000..1bac52a180 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/setup.py @@ -0,0 +1,10 @@ +from setuptools import setup + +setup( + name='sonic_platform', + version='1.0', + description='Module to initialize Celestica B3010 platforms', + + packages=['sonic_platform'], + package_dir={'sonic_platform': 'sonic_platform'}, +) diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/__init__.py new file mode 100644 index 0000000000..d3c24cb008 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import platform diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/chassis.py new file mode 100644 index 0000000000..fbc7cc034c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/chassis.py @@ -0,0 +1,441 @@ +#!/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 +# +############################################################################# + +try: + import sys + import time + import os + import re + import shutil + from sonic_platform_base.chassis_base import ChassisBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_DRAWER = 4 +NUM_FAN_PER_DRAWER = 2 +NUM_PSU = 2 +NUM_THERMAL = 13 +NUM_SFP = 56 +NUM_COMPONENT = 9 + +SFP_PORT_START = 1 +SFP_PORT_END = 48 +QSFP_PORT_START = 49 +QSFP_PORT_END = 56 + +REBOOT_CAUSE_REG = "0xA106" +BASE_CPLD_PLATFORM = "sys_cpld" +BASE_GETREG_PATH = "/sys/devices/platform/{}/getreg".format(BASE_CPLD_PLATFORM) +IPMI_GET_SYS_STATUS_LED="ipmitool raw 0x3A 0x0C 0x00 0x02 0x62" +IPMI_SET_SYS_STATUS_LED="ipmitool raw 0x3A 0x0C 0x00 0x03 0x62 {}" + +ORG_HW_REBOOT_CAUSE_FILE="/host/reboot-cause/hw-reboot-cause.txt" +TMP_HW_REBOOT_CAUSE_FILE="/tmp/hw-reboot-cause.txt" + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + sfp_status_dict={} + + #led color status + SYSLED_COLOR_VAL_MAP = {\ + 'off': '0x33',\ + 'green': '0x10',\ + 'green_blink_1hz': '0x11',\ + 'amber': '0x20'\ + } + + SYSLED_VAL_COLOR_DESC_MAP = { + 0x33: 'off',\ + 0x10: 'green',\ + 0x11: 'green_blink_1hz',\ + 0x20: 'amber'\ + } + + def __init__(self): + ChassisBase.__init__(self) + self._api_helper = APIHelper() + self.sfp_module_initialized = False + self.fan_module_initialized = False + self._watchdog = None + self._airflow_direction = None + self.__initialize_eeprom() + + self.__initialize_thermals() + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_components() + + def __initialize_sfp(self): + if not self.sfp_module_initialized: + from sonic_platform.sfp import Sfp + for index in range(0, NUM_SFP): + sfp = Sfp(index) + self._sfp_list.append(sfp) + present = sfp.get_presence() + self.sfp_status_dict[sfp.index] = '1' if present else '0' + self.sfp_module_initialized = True + + def __initialize_psu(self): + from sonic_platform.psu import Psu + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + + def __initialize_fan(self): + from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer + for fand_index in range(0, NUM_FAN_DRAWER): + drawer_fan_list=[] + for fan_index in range(0, NUM_FAN_PER_DRAWER): + fan = Fan(fand_index, fan_index) + self._fan_list.append(fan) + drawer_fan_list.append(fan) + fan_drawer = FanDrawer(fand_index, drawer_fan_list) + self._fan_drawer_list.append(fan_drawer) + self.fan_module_initialized = True + + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + def __initialize_eeprom(self): + from sonic_platform.eeprom import Eeprom + self._eeprom = Eeprom() + + def __initialize_components(self): + from sonic_platform.component import Component + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + + def initizalize_system_led(self): + return True + + def get_status_led(self): + color_str = 'N/A' + status, output = self._api_helper.run_command(IPMI_GET_SYS_STATUS_LED) + if status: + color_val = int(output, 16) & 0x33 + color_str = self.SYSLED_VAL_COLOR_DESC_MAP.get(color_val, color_str) + + return color_str + + def set_status_led(self, color): + status = False + + color_val = self.SYSLED_COLOR_VAL_MAP.get(color, None) + if color_val != None: + cmd = IPMI_SET_SYS_STATUS_LED.format(color_val) + status, res = self._api_helper.run_command(cmd) + + return status + + 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' + """ + return self._eeprom.get_mac() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + hw_reboot_cause = self._api_helper.get_register_value( + BASE_GETREG_PATH, REBOOT_CAUSE_REG) + + + # This tmp copy is to retain the reboot-cause only for the current boot + if os.path.isfile(ORG_HW_REBOOT_CAUSE_FILE): + shutil.move(ORG_HW_REBOOT_CAUSE_FILE, TMP_HW_REBOOT_CAUSE_FILE) + + if hw_reboot_cause == "0x00" and os.path.isfile(TMP_HW_REBOOT_CAUSE_FILE): + with open(TMP_HW_REBOOT_CAUSE_FILE) as hw_cause_file: + reboot_info = hw_cause_file.readline().rstrip('\n') + match = re.search(r'Reason:(.*),Time:(.*)', reboot_info) + if match is not None: + if match.group(1) == 'system': + return (self.REBOOT_CAUSE_NON_HARDWARE, 'System cold reboot') + + + if hw_reboot_cause == "0x99": + reboot_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC + description = 'ASIC Overload Reboot' + elif hw_reboot_cause == "0x88": + reboot_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU + description = 'CPU Overload Reboot' + elif hw_reboot_cause == "0x77": + reboot_cause = self.REBOOT_CAUSE_WATCHDOG + description = 'Hardware Watchdog Reset' + elif hw_reboot_cause == "0x55": + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'CPU Cold Reset' + elif hw_reboot_cause == "0x44": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'CPU Warm Reset' + elif hw_reboot_cause == "0x33": + # When NON_HARDWARE is used and device is powercycled via IPMI + # reboot cause computed as Unknown, Hence using HARDWARE_OTHER + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'Soft-Set Cold Reset' + elif hw_reboot_cause == "0x22": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'Soft-Set Warm Reset' + elif hw_reboot_cause == "0x11": + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + description = 'Power On Reset' + elif hw_reboot_cause == "0x00": + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + description = 'Power Cycle Reset' + else: + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'Hardware reason' + + return (reboot_cause, description) + + ############################################################## + ######################## SFP methods ######################### + ############################################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + Returns: + An integer, the number of sfps available on this chassis + """ + self.__initialize_sfp() + + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + self.__initialize_sfp() + + return self._sfp_list + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet1, 1 for Ethernet2 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + self.__initialize_sfp() + + try: + sfp = self._sfp_list[index - 1] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list) - 1)) + return sfp + + ############################################################## + ####################### Other methods ######################## + ############################################################## + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_helper.hwsku + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._eeprom.get_pn() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self.get_serial_number() + + def get_revision(self): + """ + Retrieves the hardware revision for the chassis + Returns: + A string containing the hardware revision for this chassis. + """ + return self._eeprom.get_revision() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True + + ############################################################## + ###################### Event methods ######################### + ############################################################## + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - bool: True if call successful, False if not; + - dict: A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, where device_id is the device ID + for this device and device_event. + The known devices's device_id and device_event was defined as table below. + ----------------------------------------------------------------- + device | device_id | device_event | annotate + ----------------------------------------------------------------- + 'fan' '' '0' Fan removed + '1' Fan inserted + + 'sfp' '' '0' Sfp removed + '1' Sfp inserted + '2' I2C bus stuck + '3' Bad eeprom + '4' Unsupported cable + '5' High Temperature + '6' Bad cable + + 'voltage' '' '0' Vout normal + '1' Vout abnormal + -------------------------------------------------------------------- + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0', '12':'1'}, + 'voltage':{'U20':'0', 'U21':'1'}} + Indicates that: + fan 0 has been removed, fan 2 has been inserted. + sfp 11 has been removed, sfp 12 has been inserted. + monitored voltage U20 became normal, voltage U21 became abnormal. + Note: For sfp, when event 3-6 happened, the module will not be avalaible, + XCVRD shall stop to read eeprom before SFP recovered from error status. + """ + sfp_dict = {} + + SFP_REMOVED = '0' + SFP_INSERTED = '1' + + SFP_PRESENT = True + SFP_ABSENT = False + + start_time = time.time() + time_period = timeout/float(1000) #Convert msecs to secs + + while time.time() < (start_time + time_period) or timeout == 0: + for sfp in self._sfp_list: + port_idx = sfp.index + if self.sfp_status_dict[port_idx] == SFP_REMOVED and \ + sfp.get_presence() == SFP_PRESENT: + sfp_dict[port_idx] = SFP_INSERTED + self.sfp_status_dict[port_idx] = SFP_INSERTED + elif self.sfp_status_dict[port_idx] == SFP_INSERTED and \ + sfp.get_presence() == SFP_ABSENT: + sfp_dict[port_idx] = SFP_REMOVED + self.sfp_status_dict[port_idx] = SFP_REMOVED + + if sfp_dict: + return True, {'sfp':sfp_dict} + + time.sleep(0.5) + + return True, {'sfp':{}} # Timeout + + def get_airflow_direction(self): + if self._airflow_direction == None: + try: + vendor_extn = self._eeprom.get_vendor_extn() + airflow_type = vendor_extn.split()[2][2:4] # Either 0xFB or 0xBF + if airflow_type == 'FB': + direction = 'exhaust' + elif airflow_type == 'BF': + direction = 'intake' + else: + direction = 'N/A' + except (AttributeError, IndexError): + direction = 'N/A' + + self._airflow_direction = direction + + return self._airflow_direction diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/component.py new file mode 100644 index 0000000000..185a62ef6a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/component.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +import os.path +import re + +try: + #from sonic_platform_base.component_base import ComponentBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NAME_IDX = 0 +DESC_IDX = 1 +VER_API_IDX = 2 + +BASE_CPLD_PLATFORM = "sys_cpld" +SW_CPLD_PLATFORM = "questone2" +PLATFORM_SYSFS_PATH = "/sys/devices/platform/" + +FPGA_GETREG_PATH = "{}/{}/FPGA/getreg".format( + PLATFORM_SYSFS_PATH, SW_CPLD_PLATFORM) +BASE_GETREG_PATH = "{}/{}/getreg".format( + PLATFORM_SYSFS_PATH, BASE_CPLD_PLATFORM) +SW_CPLD1_GETREG_PATH = "{}/{}/CPLD1/getreg".format( + PLATFORM_SYSFS_PATH, SW_CPLD_PLATFORM) +SW_CPLD2_GETREG_PATH = "{}/{}/CPLD2/getreg".format( + PLATFORM_SYSFS_PATH, SW_CPLD_PLATFORM) +BIOS_VER_PATH = "/sys/class/dmi/id/bios_version" + +BASE_CPLD_VER_REG = "0xA100" +COME_CPLD_VER_REG = "0xA1E0" +SW_CPLD_VER_REG = "0x00" +FPGA_VER_REG = "0x00" + +UNKNOWN_VER = "N/A" +ONIE_VER_CMD = "cat /host/machine.conf" +SSD_VER_CMD = "smartctl -i /dev/sda" + +class Component(): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_index): + COMPONENT_LIST = [ + ("BIOS", "Basic input/output System", self.__get_bios_ver), + ("ONIE", "Open Network Install Environment", self.__get_onie_ver), + ("BMC", "Baseboard Management Controller", self.__get_bmc_ver), + ("FPGA", "FPGA for transceiver EEPROM access and other component I2C access", self.__get_fpga_ver), + ("CPLD COMe", "COMe board CPLD", self.__get_cpld_ver), + ("CPLD BASE", "CPLD for board functions, fan control and watchdog", self.__get_cpld_ver), + ("CPLD SW1", "CPLD for port control SFP(1-24)", self.__get_cpld_ver), + ("CPLD SW2", "CPLD for port control SFP(25-48) QSFP(49-56)", self.__get_cpld_ver), + ("SSD", "Solid State Drive - {}", self.__get_ssd_ver), + ] + + self.index = component_index + self.name = COMPONENT_LIST[self.index][NAME_IDX] + self.description = COMPONENT_LIST[self.index][DESC_IDX] + self.__get_version = COMPONENT_LIST[self.index][VER_API_IDX] + self._api_helper = APIHelper() + + def __get_bios_ver(self): + return self._api_helper.read_one_line_file(BIOS_VER_PATH) + + def __get_onie_ver(self): + onie_ver = "N/A" + status, raw_onie_data = self._api_helper.run_command(ONIE_VER_CMD) + if status: + ret = re.search(r"(?<=onie_version=).+[^\n]", raw_onie_data) + if ret != None: + onie_ver = ret.group(0) + return onie_ver + + def __get_bmc_ver(self): + cmd="ipmitool mc info | grep 'Firmware Revision'" + status, raw_ver=self._api_helper.run_command(cmd) + if status: + bmc_ver=raw_ver.split(':')[-1].strip() + return bmc_ver + else: + return UNKNOWN_VER + + def __get_fpga_ver(self): + version_raw = self._api_helper.get_register_value(FPGA_GETREG_PATH, FPGA_VER_REG) + return "{}.{}".format(int(version_raw[2:][:4], 16), int(version_raw[2:][4:], 16)) if version_raw else UNKNOWN_VER + + def __get_cpld_ver(self): + cpld_api_param = { + 'CPLD COMe': (BASE_GETREG_PATH, COME_CPLD_VER_REG), + 'CPLD BASE': (BASE_GETREG_PATH, BASE_CPLD_VER_REG), + 'CPLD SW1': (SW_CPLD1_GETREG_PATH, SW_CPLD_VER_REG), + 'CPLD SW2': (SW_CPLD2_GETREG_PATH, SW_CPLD_VER_REG), + } + api_param = cpld_api_param[self.name] + + cpld_ver = self._api_helper.get_register_value(api_param[0], api_param[1]) + return "{}.{}".format(int(cpld_ver[2], 16), int(cpld_ver[3], 16)) if cpld_ver else UNKNOWN_VER + + def __get_ssd_ver(self): + ssd_ver = "N/A" + status, raw_ssd_data = self._api_helper.run_command(SSD_VER_CMD) + if status: + ret = re.search(r"Firmware Version: +(.*)[^\\]", raw_ssd_data) + if ret != None: + ssd_ver = ret.group(1) + return ssd_ver + + def __get_ssd_model(self): + model = "N/A" + + status, raw_ssd_data = self._api_helper.run_command(SSD_VER_CMD) + if status: + ret = re.search(r"Device Model: +(.*)[^\\]", raw_ssd_data) + if ret != None: + try: + model = ret.group(1) + except (IndexError): + pass + return model + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + # For SSD get the model name from device + if self.name == "SSD": + return self.description.format(self.__get_ssd_model()) + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + return self.__get_version() diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/eeprom.py new file mode 100644 index 0000000000..ff08cd9498 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/eeprom.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os + import sys + import re + import json + import fcntl + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +NULL = 'N/A' +EEPROM_TMP_FILE = '/tmp/eeprom_dump.json' + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + for i2cbus in range(2): + path_prefix = "/sys/class/i2c-adapter/i2c-{0}/".format(i2cbus) + with open(path_prefix + "name") as fd: + if 'SMBus iSMT adapter at ' in fd.readline(): + self._eeprom_path = path_prefix + "{0}-0056/eeprom".format(i2cbus) + break + super(Eeprom, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search('(0x[0-9a-fA-F]{2})\s+\d+\s+(.+)', line) + if match is not None: + idx = match.group(1) + value = match.group(2).rstrip('\0') + + _eeprom_info_dict[idx] = value + except Exception: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + eeprom_dict = {} + + if os.path.exists(EEPROM_TMP_FILE): + with open(EEPROM_TMP_FILE, 'r') as fd: + eeprom_dict = json.load(fd) + + return eeprom_dict + + original_stdout = sys.stdout + sys.stdout = StringIO() + rv = -1 + try: + rv = self.read_eeprom_db() + except BaseException: + pass + + if rv == 0: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + eeprom_dict = self.__parse_output(decode_output) + else: + e = self.read_eeprom() + if e is None: + sys.stdout = original_stdout + return {} + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return {} + + eeprom_dict = self.__parse_output(decode_output) + + if len(eeprom_dict) != 0: + with open(EEPROM_TMP_FILE, 'w') as fd: + fcntl.flock(fd, fcntl.LOCK_EX) + json.dump(eeprom_dict, fd) + fcntl.flock(fd, fcntl.LOCK_UN) + + return eeprom_dict + + def get_eeprom(self): + return self._eeprom + + def get_product(self): + return self._eeprom.get('0x21', NULL) + + def get_pn(self): + return self._eeprom.get('0x22', NULL) + + def get_serial(self): + return self._eeprom.get('0x23', NULL) + + def get_mac(self): + return self._eeprom.get('0x24', NULL) + + def get_revision(self): + return self._eeprom.get('0x26', NULL) + + def get_vendor_extn(self): + return self._eeprom.get('0xFD', NULL) diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/fan.py new file mode 100644 index 0000000000..6a1faa44eb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/fan.py @@ -0,0 +1,345 @@ +#!/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 +# +############################################################################# + +try: + from sonic_platform_base.fan_base import FanBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NOT_AVAILABLE = 'N/A' + +FAN_NAME_TEMPLATE = "{}Fan{}{}" +NUM_FAN_TRAYS = 4 +NUM_FANS_PER_TRAY = 2 +FAN_SPEED_TOLERANCE = 20 +MAX_RPM_FRONT=23000 +MAX_RPM_REAR=20500 +MAX_RPM_PSU=22600 +FAN_DIR_BASE = 0x41 +FAN_LED_BASE = 0x04 +FAN_FRU_BASE = 0x05 +FAN_STATUS_BASE = 0x00 +FAN_SID_BASE = 0x80 +PSU_FAN_SID_BASE = 0x8a +PSU_FRU_BASE = 0x03 + + +IPMI_FAN_DIR="ipmitool raw 0x3a 0x0c 0x00 0x02 {}" +IPMI_GET_SPEED="ipmitool raw 0x04 0x2d {}" +IPMI_GET_CPLD_PWM="ipmitool raw 0x3a 0x0c 0x00 0x02 {}" +IPMI_GET_PRESENCE="ipmitool raw 0x3a 0x03 0x03 {}" +IPMI_GET_MODEL="ipmitool fru list {} | grep 'Board Part Number'" +IPMI_GET_SERIAL="ipmitool fru list {} | grep 'Board Serial'" +IPMI_GET_PSU_MODEL="ipmitool fru list {} | grep 'Product Name'" +IPMI_GET_PSU_SPEED="ipmitool raw 0x04 0x2d {}" +IPMI_SET_STATUS_LED="ipmitool raw 0x3a 0x0a {} {}" +IPMI_GET_STATUS_LED="ipmitool raw 0x3a 0x0b {}" + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.is_psu_fan = is_psu_fan + self._api_helper = APIHelper() + self.index = (self.fan_tray_index * 2) + self.fan_index + self.name = None + if self.is_psu_fan: + self.psu_index = psu_index + self.max_speed = MAX_RPM_PSU + self._fan_sid_offset = PSU_FAN_SID_BASE + self.psu_index + self._fan_status_offset = FAN_STATUS_BASE + NUM_FAN_TRAYS + self.psu_index + else: + self._fan_status_offset = FAN_STATUS_BASE + self.fan_tray_index + self._fan_fru_offset = FAN_FRU_BASE + self.fan_tray_index + self._fan_dir_offset = FAN_DIR_BASE + (self.fan_tray_index * 4) + if self.fan_tray_index > 1: + # Questone CPLD firmware is used and hence FAN 3 will be missing + # There are only 4 FAN trays in this platform + self._fan_dir_offset = self._fan_dir_offset + 4 + + self._fan_speed_offset = self._fan_dir_offset - 1 + self._fan_led_offset = FAN_LED_BASE + self.fan_tray_index + + if fan_index % 2 == 0: + # Front FAN + self.is_front = True + self.max_speed = MAX_RPM_FRONT + self._fan_sid_offset = FAN_SID_BASE + 1 + (self.fan_tray_index * NUM_FANS_PER_TRAY) + else: + # Rear FAN + self.is_front = False + self.max_speed = MAX_RPM_REAR + self._fan_sid_offset = FAN_SID_BASE + (self.fan_tray_index * NUM_FANS_PER_TRAY) + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = NOT_AVAILABLE + + if self.is_psu_fan: + cmd = IPMI_GET_PSU_MODEL.format(PSU_FRU_BASE + self.psu_index) + status, output = self._api_helper.run_command(cmd) + if status and output: + model = output.split(':')[-1] + if len(model) > 0: + if model[-2:] == ' B': + direction = self.FAN_DIRECTION_INTAKE + else: + direction = self.FAN_DIRECTION_EXHAUST + else: + cmd = IPMI_FAN_DIR.format(self._fan_dir_offset) + status, output = self._api_helper.run_command(cmd) + if status: + dir_num = int(output, 16) & 0x0C + if dir_num == 0x0: + direction = self.FAN_DIRECTION_EXHAUST + elif dir_num == 0x8: + direction = self.FAN_DIRECTION_INTAKE + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + + if not self.is_psu_fan: + multiplier = 150.0 + else: + multiplier = 100.0 + + cmd = IPMI_GET_PSU_SPEED.format(self._fan_sid_offset) + status, output = self._api_helper.run_command(cmd) + if status: + raw_speed = output.split()[0] + rpm_speed = int(raw_speed, 16) * multiplier + speed = int((rpm_speed/self.max_speed) * 100) + + return speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + """ + target_speed = 0 + + if self.is_psu_fan: + # Ignored for tolerance check + return self.get_speed() + + cmd = IPMI_GET_CPLD_PWM.format(self._fan_speed_offset) + status, output = self._api_helper.run_command(cmd) + if status: + fan_pwm = int(output, 16) + target_speed = round(fan_pwm / 255 * 100) + + return target_speed + + 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 FAN_SPEED_TOLERANCE + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + Notes: + pwm setting mode must set as Manual + manual: systemctl stop fanctrl.service + auto: systemctl start fanctrl.service + """ + + # FAN speed is controlled by BCM always + return False + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + # There is no per Fan LED + return True + + def drawer_set_status_led(self, color): + status = False + + color_dict = {\ + self.STATUS_LED_COLOR_OFF: 0,\ + self.STATUS_LED_COLOR_AMBER: 1,\ + self.STATUS_LED_COLOR_RED: 1,\ + self.STATUS_LED_COLOR_GREEN: 2\ + } + + if not self.is_psu_fan: + cmd = IPMI_SET_STATUS_LED.format(self._fan_led_offset, color_dict.get(color, 0)) + status, _ = self._api_helper.run_command(cmd) + + return status + + + def get_status_led(self): + """ + Gets the state of the fan status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + + Note: + Output + STATUS_LED_COLOR_GREEN = "green" + STATUS_LED_COLOR_AMBER = "amber" + STATUS_LED_COLOR_RED = "red" + STATUS_LED_COLOR_OFF = "off" + + Input + 0x1: green + 0x2: red + 0x3: off + """ + status = NOT_AVAILABLE + color_dict = {\ + 0: self.STATUS_LED_COLOR_OFF,\ + 1: self.STATUS_LED_COLOR_AMBER,\ + 2: self.STATUS_LED_COLOR_GREEN\ + } + + if not self.is_psu_fan: + cmd = IPMI_GET_STATUS_LED.format(self._fan_led_offset) + status, output = self._api_helper.run_command(cmd) + if status: + color = int(output, 16) + status = color_dict.get(color, status) + + return status + + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + + if not self.name: + if not self.is_psu_fan: + psu_name = "" + fan_id = " {}".format(self.fan_tray_index + 1) + fan_type = " Front" if self.is_front else " Rear" + else: + psu_name = "PSU {} ".format(self.psu_index + 1) + fan_id = " {}".format(self.fan_tray_index + 1) + fan_type = "" + + self.name = FAN_NAME_TEMPLATE.format(psu_name, fan_id, fan_type) + + return self.name + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + + presence = False + + cmd = IPMI_GET_PRESENCE.format(self._fan_status_offset) + status, output = self._api_helper.run_command(cmd) + if status and output == "00": + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = NOT_AVAILABLE + + if not self.is_psu_fan: + cmd = IPMI_GET_MODEL.format(self._fan_fru_offset) + status, output = self._api_helper.run_command(cmd) + if status and output: + return output.split()[-1] + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial = NOT_AVAILABLE + + if not self.is_psu_fan: + cmd = IPMI_GET_SERIAL.format(self._fan_fru_offset) + status, output = self._api_helper.run_command(cmd) + if status and output: + return output.split()[-1] + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_speed() > 0 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + if not self.is_psu_fan: + return True + + return False diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/fan_drawer.py new file mode 100644 index 0000000000..14ea5c9005 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/fan_drawer.py @@ -0,0 +1,82 @@ +#!/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 +# +############################################################################# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(FanDrawerBase): + + def __init__(self, index, fan_list): + FanDrawerBase.__init__(self) + + self._fan_list = fan_list + self._index = index + 1 + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + Args: + color: A string representing the color with which to set the + fan drawer status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return self._fan_list[0].drawer_set_status_led(color) + + def get_status_led(self): + """ + Gets the state of the fan drawer LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._fan_list[0].get_status_led() + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return 'Drawer {}'.format(self._index) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + return self._fan_list[0].get_presence() + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._fan_list[0].get_model() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._fan_list[0].get_serial() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self._fan_list[0].get_status() diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/helper.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/helper.py new file mode 100644 index 0000000000..3a861cb575 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/helper.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python + +import os +import struct +import subprocess +from mmap import * +from sonic_py_common.device_info import get_platform_and_hwsku + +SCALE = 16 +BIN_BITS = 8 +EMPTY_STRING = "" +HOST_CHK_CMD = "docker > /dev/null 2>&1" + + +class APIHelper(): + + def __init__(self): + (self.platform, self.hwsku) = get_platform_and_hwsku() + + def get_register_value(self, getreg_path, register): + cmd = "echo {1} > {0}; cat {0}".format(getreg_path, register) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + return raw_data.strip().decode('UTF-8') if not err else None + + def hex_to_bin(self, ini_string): + return bin(int(ini_string, SCALE)).zfill(BIN_BITS) + + def is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except Exception: + status = False + return status, result + + def run_command(self, cmd): + status = True + result = "" + try: + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err.decode('UTF-8') == '': + result = raw_data.strip().decode('UTF-8') + except Exception: + status = False + return status, result + + def run_interactive_command(self, cmd): + try: + os.system(cmd) + except Exception: + return False + return True + + def read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def read_one_line_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.readline() + return data.strip() + except IOError: + pass + return None + + def search_file_by_contain(self, directory, search_str, file_start): + for dirpath, dirnames, files in os.walk(directory): + for name in files: + file_path = os.path.join(dirpath, name) + if name.startswith(file_start) and search_str in self.read_txt_file(file_path): + return dirpath + return None + + def write_file(self, file_path, data): + try: + with open(file_path, 'w') as fd: + fd.write(str(data)) + return True + except Exception: + pass + return False + + def ipmi_raw(self, netfn, cmd): + status = True + result = "" + try: + cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd)) + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def ipmi_fru_id(self, id, key=None): + status = True + result = "" + try: + cmd = "ipmitool fru print {}".format(str( + id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key)) + + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def ipmi_set_ss_thres(self, id, threshold_key, value): + status = True + result = "" + try: + cmd = "ipmitool sensor thresh '{}' {} {}".format( + str(id), str(threshold_key), str(value)) + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def fru_decode_product_serial(self, data): + + if data and data[4] != 00: + start_product_info = ord(data[4]) * 8 + start_format_version = start_product_info + start_product_info = start_format_version + 1 + start_product_Lang_code = start_product_info + 1 + start_product_Manu_name = start_product_Lang_code + 1 + start_product_Manu_name_length = ord(data[start_product_Manu_name]) & 0x0F + start_product_name = start_product_Manu_name + start_product_Manu_name_length + 1 + start_product_name_length = ord(data[start_product_name]) & 0x0F + start_product_module_number = start_product_name + start_product_name_length +1 + start_product_module_number_length = ord(data[start_product_module_number]) & 0x0F + start_product_version = start_product_module_number + start_product_module_number_length +1 + start_product_version_length = ord(data[start_product_version]) & 0x0F + start_product_serial_number = start_product_version + start_product_version_length +1 + start_product_serial_number_length = ord(data[start_product_serial_number]) & 0x1F + return data[start_product_serial_number+1:start_product_serial_number+start_product_serial_number_length+1] + return "N/A" + + def fru_decode_product_model(self, data): + if data and data[4] != 00: + start_product_info = ord(data[4]) * 8 + start_format_version = start_product_info + start_product_info = start_format_version + 1 + start_product_lang_code = start_product_info + 1 + start_product_manu_name = start_product_lang_code + 1 + start_product_manu_name_length = ord(data[start_product_manu_name]) & 0x1F + start_product_name = start_product_manu_name + start_product_manu_name_length + 1 + start_product_name_length = ord(data[start_product_name]) & 0x1F + start_product_module_number = start_product_name + start_product_name_length + 1 + start_product_module_number_length = ord(data[start_product_module_number]) & 0x1F + return data[start_product_module_number + 1: start_product_module_number +start_product_module_number_length + 1] + return "N/A" + + def fru_decode_product_name(self, data): + + if data and data[4] != 00: + start_product_info = ord(data[4]) * 8 + start_format_version = start_product_info + start_product_info = start_format_version + 1 + start_product_Lang_code = start_product_info + 1 + start_product_Manu_name = start_product_Lang_code + 1 + start_product_Manu_name_length = ord(data[start_product_Manu_name]) & 0x0F + start_product_name = start_product_Manu_name + start_product_Manu_name_length + 1 + start_product_name_length = ord(data[start_product_name]) & 0x0F + return data[start_product_name+1: start_product_name+start_product_name_length+1] + + return "N/A" + + def read_eeprom_sysfs(self,sys_path,sysfs_file): + sysfs_path = os.path.join(sys_path, sysfs_file) + try: + with open(sysfs_path, mode='rb', buffering=0) as fd: + data = fd.read(256) + return data + except Exception: + pass + return None diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/pcie.py new file mode 100644 index 0000000000..2f7931d42b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/pcie.py @@ -0,0 +1,15 @@ +# +# pcie_base.py +# +# Abstract base class for implementing platform-specific +# PCIE functionality for SONiC +# + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError (str(e) + " - required module not found") + +class Pcie(PcieUtil): + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/platform.py new file mode 100644 index 0000000000..c9ba822ac0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/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/questone2/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/psu.py new file mode 100644 index 0000000000..8c36c61e1f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/psu.py @@ -0,0 +1,265 @@ +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.psu_base import PsuBase + from .helper import APIHelper + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +IPMI_SENSOR_NETFN = "0x04" +IPMI_SENSOR_READ_CMD = "0x2D {}" +IPMI_SENSOR_THRESH_CMD = "0x27 {}" +IPMI_FRU_MODEL_KEY = "Product Name" +IPMI_FRU_SERIAL_KEY = "Product Serial" + +MAX_PSU_POWER = 550 #Watts +psu_ipmi_id = {\ + 1: {\ + "TEMP": "0x0d",\ + "VOUT": "0x0f",\ + "COUT": "0x10",\ + "POUT": "0x11",\ + "STATUS": "0x72",\ + "FRU": 3,\ + }, + 2: {\ + "TEMP": "0x17",\ + "VOUT": "0x19",\ + "COUT": "0x1a",\ + "POUT": "0x1b",\ + "STATUS": "0x73",\ + "FRU": 4,\ + } +} + +ANALOG_READ_OFFSET = 0 +EVENT_0_7_OFFSET = 2 +EVENT_8_14_OFFSET = 3 + +FRU_SERIAL = 4 +FRU_MODEL = 1 + + +class Psu(PsuBase): + """Platform-specific Psu class""" + + def __init__(self, psu_index): + PsuBase.__init__(self) + self.index = psu_index+1 + # PSU has only one FAN + fan = Fan(0, 0, is_psu_fan=True, psu_index=psu_index) + self._fan_list.append(fan) + self._api_helper = APIHelper() + + def get_voltage(self): + """ + Retrieves current PSU voltage output + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + psu_voltage = 0.0 + psu_vout_key = psu_ipmi_id[self.index]['VOUT'] + status, output = self._api_helper.ipmi_raw(IPMI_SENSOR_NETFN,\ + IPMI_SENSOR_READ_CMD.format(psu_vout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx10^-1 + psu_voltage = int(value, 16) / 10.0 + + return psu_voltage + + def get_voltage_high_threshold(self): + return 12.6 + + def get_voltage_low_threshold(self): + return 11.4 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + psu_current = 0.0 + psu_cout_key = psu_ipmi_id[self.index]['COUT'] + status, output = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_cout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx3x10^-1 + psu_current = int(value, 16) * 3 / 10.0 + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + Returns: + A float number, the power in watts, e.g. 302.6 + """ + psu_power = 0.0 + psu_pout_key = psu_ipmi_id[self.index]['POUT'] + status, output = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx5 + psu_power = int(value, 16) * 5 + return psu_power + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.get_presence(): + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return "blinking green" + else: + return "N/A" + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + # PSU's ambient temperature sensor is considered as the PSU temperature + psu_temp = 0.0 + psu_temp_id = psu_ipmi_id[self.index]['TEMP'] + status, output = self._api_helper.ipmi_raw(IPMI_SENSOR_NETFN,\ + IPMI_SENSOR_READ_CMD.format(psu_temp_id)) + if status: + value = output.split()[ANALOG_READ_OFFSET] + psu_temp = float(int(value, 16)) + + return psu_temp + + def get_maximum_supplied_power(self): + """ + Retrieves the maximum supplied power by PSU + Returns: + A float number, the maximum power output in Watts. + e.g. 1200.1 + """ + + return MAX_PSU_POWER + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return "PSU {}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + psu_presence = False + psu_pstatus_key = psu_ipmi_id[self.index]['STATUS'] + status, raw_status_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pstatus_key)) + status_byte = raw_status_read.split()[EVENT_0_7_OFFSET] + + if status: + psu_presence = True if int(status_byte, 16) & 0x01 == 0x01 else False + + return psu_presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = "Unknown" + if self.get_presence(): + ipmi_fru_idx = psu_ipmi_id[self.index]['FRU'] + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_MODEL_KEY) + + fru_pn_list = raw_model.split(':')[-1] + model = fru_pn_list.strip() + else: + model = "N/A" + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial = "Unknown" + if self.get_presence(): + ipmi_fru_idx = psu_ipmi_id[self.index]['FRU'] + status, raw_serial = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_SERIAL_KEY) + + fru_sr_list = raw_serial.split(':')[-1] + serial = fru_sr_list.strip() + else: + model = "N/A" + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + psu_status = False + psu_pstatus_key = psu_ipmi_id[self.index]['STATUS'] + status, raw_status_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pstatus_key)) + status_byte = raw_status_read.split()[EVENT_0_7_OFFSET] + + if status: + psu_status = False if int(status_byte, 16) & 0x08 == 0x08 else True + + return psu_status + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/sfp.py new file mode 100644 index 0000000000..66950af042 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/sfp.py @@ -0,0 +1,197 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# +import time + +try: + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" + +QSFP_PORT_START = 49 +QSFP_PORT_END = 56 +SFP_PORT_START = 1 +SFP_PORT_END = 48 + +PORT_INFO_PATH = '/sys/class/questone2_fpga' +SFP_I2C_START = 2 + + +class Sfp(SfpOptoeBase): + """Platform-specific Sfp class""" + + # Path to QSFP sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + + def __init__(self, sfp_index): + SfpOptoeBase.__init__(self) + # Init index + self.index = sfp_index + 1 + self.sfp_type, self.port_name = self.__get_sfp_info() + self._api_helper = APIHelper() + self.platform = self._api_helper.platform + self.hwsku = self._api_helper.hwsku + + # Init eeprom path + self.eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'.format(SFP_I2C_START+sfp_index) + + def __get_sfp_info(self): + port_name = "Unknown" + sfp_type = "Unknown" + + if self.index >= QSFP_PORT_START and self.index <= QSFP_PORT_END: + sfp_type = QSFP_TYPE + port_name = sfp_type + str(self.index - QSFP_PORT_START + 1) + elif self.index >= SFP_PORT_START and self.index <= SFP_PORT_END: + sfp_type = SFP_TYPE + port_name = sfp_type + str(self.index) + return sfp_type, port_name + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.platform]) + hwsku_path = "/".join([platform_path, self.hwsku] + ) if self._api_helper.is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def get_eeprom_path(self): + return self.eeprom_path + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reg_status = self._api_helper.read_one_line_file( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_reset"])) + + return (int(reg_status) == 0) + + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + if self.sfp_type != QSFP_TYPE: + return False + + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_reset"]), "w") + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(0)) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_reset"]), "w") + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + + reg_file.seek(0) + reg_file.write(hex(1)) + reg_file.close() + + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_lpmode"]), "w") + except IOError as e: + return False + + if lpmode: + value=1 + else: + value=0 + reg_file.write(hex(value)) + reg_file.close() + + return True + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + + reg_status = self._api_helper.read_one_line_file( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_lpmode"])) + + return (int(reg_status) == 1) + + def get_position_in_parent(self): + return self.index + + def is_replaceable(self): + return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.physical_to_logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + # Get path for access port presence status + sysfs_filename = "sfp_modabs" if self.sfp_type == SFP_TYPE else "qsfp_modprs" + reg_path = "/".join([PORT_INFO_PATH, self.port_name, sysfs_filename]) + + content = self._api_helper.read_one_line_file(reg_path) + reg_value = int(content) + + return (reg_value == 0) + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and not self.get_reset_status() diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/thermal.py similarity index 50% rename from device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py rename to platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/thermal.py index 9ecf12218d..d3d96b1e3e 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/thermal.py +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/thermal.py @@ -19,9 +19,8 @@ except ImportError as e: IPMI_SENSOR_NETFN = "0x04" IPMI_SS_READ_CMD = "0x2D {}" IPMI_SS_THRESHOLD_CMD = "0x27 {}" -DEFUALT_LOWER_TRESHOLD = 0.0 HIGH_TRESHOLD_SET_KEY = "unc" - +DEFAULT_VAL = 'N/A' class Thermal(ThermalBase): """Platform-specific Thermal class""" @@ -30,26 +29,30 @@ class Thermal(ThermalBase): ThermalBase.__init__(self) self._api_helper = APIHelper() self.index = thermal_index - self.THERMAL_LIST = [ - ('TEMP_FAN_U52', 'Fan Tray Middle Temperature Sensor', '0x00'), - ('TEMP_FAN_U17', 'Fan Tray Right Temperature Sensor', '0x01'), - ('TEMP_SW_U52', 'Switchboard Left Inlet Temperature Sensor', '0x02'), - ('TEMP_SW_U16', 'Switchboard Right Inlet Temperature Sensor', '0x03'), - ('TEMP_BB_U3', 'Baseboard Temperature Sensor', '0x04'), - ('TEMP_CPU', 'CPU Internal Temperature Sensor', '0x05'), - ('TEMP_SW_Internal', 'ASIC Internal Temperature Sensor', '0x61'), - ('SW_U04_Temp', 'IR3595 Chip Left Temperature Sensor', '0x4F'), - ('SW_U14_Temp', 'IR3595 Chip Right Temperature Sensor', '0x56'), - ('SW_U4403_Temp', 'IR3584 Chip Temperature Sensor', '0x5D'), + thermal_list = [\ + ('Base_Temp_U5', '0x01', 'Baseboard Right Temp'),\ + ('Base_Temp_U7', '0x02', 'Baseboard Left Temp'),\ + ('Switch_Temp_U31', '0x03', 'ASIC External Front Temp'),\ + ('Switch_Temp_U30', '0x04', 'ASIC External Rear Temp'),\ + ('Switch_Temp_U29', '0x05', 'Switchboard Right Temp'),\ + ('Switch_Temp_U28', '0x06', 'Switchboard Left Temp'),\ + ('CPU_Temp', '0x07', 'CPU Internal Temp'),\ + ('Switch_U33_Temp', '0x4C', 'IR3595 Chip Temp'),\ + ('Switch_U21_Temp', '0x56', 'IR3584 Chip Temp'),\ + ('PSUL_Temp1', '0x0D', 'PSU 1 Ambient Temp'),\ + ('PSUL_Temp2', '0x0E', 'PSU 1 Hotspot Temp'),\ + ('PSUR_Temp1', '0x17', 'PSU 2 Ambient Temp'),\ + ('PSUR_Temp2', '0x18', 'PSU 2 Hotspot Temp'),\ ] - self.sensor_id = self.THERMAL_LIST[self.index][0] - self.sensor_des = self.THERMAL_LIST[self.index][1] - self.sensor_reading_addr = self.THERMAL_LIST[self.index][2] + self.sensor_id = thermal_list[self.index][0] + self.sensor_reading_addr = thermal_list[self.index][1] + self.sensor_name = thermal_list[self.index][2] - def __set_threshold(self, key, value): - print('{} {}'.format(key, value)) + temp = self.get_temperature(True) + self.minimum_thermal = temp + self.maximum_thermal = temp - def get_temperature(self): + def get_temperature(self, skip_record=False): """ Retrieves current temperature reading from thermal Returns: @@ -62,7 +65,20 @@ class Thermal(ThermalBase): if status and len(raw_ss_read.split()) > 0: ss_read = raw_ss_read.split()[0] temperature = float(int(ss_read, 16)) - return temperature + + if temperature != 0.0: + if not skip_record: + # Record maximum + if temperature > self.maximum_thermal: + self.maximum_thermal = temperature + + # Record minimum + if temperature < self.minimum_thermal: + self.minimum_thermal = temperature + + return temperature + else: + return DEFAULT_VAL def get_high_threshold(self): """ @@ -77,7 +93,10 @@ class Thermal(ThermalBase): if status and len(raw_up_thres_read.split()) > 6: ss_read = raw_up_thres_read.split()[4] high_threshold = float(int(ss_read, 16)) - return high_threshold + if high_threshold != 0.0: + return high_threshold + else: + return DEFAULT_VAL def get_low_threshold(self): """ @@ -86,7 +105,7 @@ class Thermal(ThermalBase): A float number, the low threshold temperature of thermal in Celsius up to nearest thousandth of one degree Celsius, e.g. 30.125 """ - return DEFUALT_LOWER_TRESHOLD + return DEFAULT_VAL def set_high_threshold(self, temperature): """ @@ -97,7 +116,8 @@ class Thermal(ThermalBase): Returns: A boolean, True if threshold is set successfully, False if not """ - status, ret_txt = self._api_helper.ipmi_set_ss_thres(self.sensor_id, HIGH_TRESHOLD_SET_KEY, temperature) + status, ret_txt = self._api_helper.ipmi_set_ss_thres( + self.sensor_id, HIGH_TRESHOLD_SET_KEY, temperature) return status def set_low_threshold(self, temperature): @@ -111,13 +131,53 @@ class Thermal(ThermalBase): """ return False + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + high_critical_threshold = 0.0 + status, raw_up_thres_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_THRESHOLD_CMD.format(self.sensor_reading_addr)) + if status and len(raw_up_thres_read.split()) > 6: + ss_read = raw_up_thres_read.split()[5] + high_critical_threshold = float(int(ss_read, 16)) + if high_critical_threshold != 0.0: + return high_critical_threshold + else: + return DEFAULT_VAL + + def get_minimum_recorded(self): + """ + Retrieves the minimum recorded temperature of thermal + Returns: + A float number, the minimum recorded temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self.minimum_thermal + + def get_maximum_recorded(self): + """ + Retrieves the maximum recorded temperature of thermal + Returns: + A float number, the maximum recorded temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self.maximum_thermal + + ############################################################## + ###################### Device methods ######################## + ############################################################## + def get_name(self): """ Retrieves the name of the thermal device Returns: string: The name of the thermal device """ - return self.THERMAL_LIST[self.index][0] + return self.sensor_name def get_presence(self): """ @@ -127,22 +187,6 @@ class Thermal(ThermalBase): """ return True if self.get_temperature() > 0 else False - def get_model(self): - """ - Retrieves the model number (or part number) of the device - Returns: - string: Model/part number of device - """ - return self.sensor_des - - def get_serial(self): - """ - Retrieves the serial number of the device - Returns: - string: Serial number of device - """ - return "Unknown" - def get_status(self): """ Retrieves the operational status of the device @@ -150,3 +194,11 @@ class Thermal(ThermalBase): A boolean value, True if device is operating properly, False if not """ return self.get_presence() + + def is_replaceable(self): + """ + Retrieves whether thermal module is replaceable + Returns: + A boolean value, True if replaceable, False if not + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/watchdog.py new file mode 100644 index 0000000000..07b2ef5cf6 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/sonic_platform/watchdog.py @@ -0,0 +1,268 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Qeastone2 +# +# Watchdog contains an implementation of SONiC Platform Base API +# +############################################################################# +import subprocess + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +I2C_WDT_BUS_ID=60 +I2C_WDT_DEV_ID=0x0d +I2C_WDT_RESET_SRC_REG=0x06 +I2C_WDT_CTRL_REG=0x81 +I2C_WDT_SET_TIMER_L_REG=0x82 +I2C_WDT_SET_TIMER_M_REG=0x83 +I2C_WDT_SET_TIMER_H_REG=0x84 +I2C_WDT_ARM_REG=0x85 +I2C_WDT_TIMER_L_REG=0x86 +I2C_WDT_TIMER_M_REG=0x87 +I2C_WDT_TIMER_H_REG=0x88 + +WDT_ENABLE=0x1 +WDT_DISABLE=0x0 +WDT_KEEPALIVE=0x1 +WDT_COMMON_ERROR=-1 +DEFAULT_TIMEOUT=180 + +class Watchdog(WatchdogBase): + + def __init__(self): + # Set default value + self.armed = True if self._active() else False + self.timeout = self._gettimeout() + #self._disable() + + def _i2cget_cmd(self, reg): + cmd = "i2cget -y -f {} {} {} b".format(I2C_WDT_BUS_ID, I2C_WDT_DEV_ID, + reg) + return cmd + + def _i2cset_cmd(self, reg, val): + cmd = "i2cset -y -f {} {} {} {}".format(I2C_WDT_BUS_ID, I2C_WDT_DEV_ID, + reg, val) + return cmd + + def _getstatusoutput(self, cmd): + try: + data = subprocess.check_output(cmd, shell=True, + universal_newlines=True, stderr=subprocess.STDOUT) + status = 0 + except subprocess.CalledProcessError as ex: + data = ex.output + status = ex.returncode + if data[-1:] == '\n': + data = data[:-1] + return status, data + + def _active(self): + """ + WDT is active or not + """ + status, data = self._getstatusoutput(self._i2cget_cmd(I2C_WDT_CTRL_REG)) + if status: + pass + return True if data == "0x01" else False + + def _enable(self): + """ + Turn on the watchdog timer + """ + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_CTRL_REG, + WDT_ENABLE)) + if status: + pass + + def _disable(self): + """ + Turn off the watchdog timer + """ + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_CTRL_REG, + WDT_DISABLE)) + if status: + pass + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + self._settimeleft(0) + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_ARM_REG, + WDT_KEEPALIVE)) + if status: + pass + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + ms = seconds * 1000 + ms_low_byte = ms & 0xff + ms_media_byte = (ms >> 8) & 0xff + ms_high_byte = (ms >> 16) & 0xff + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_SET_TIMER_L_REG, + ms_low_byte)) + if status: + pass + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_SET_TIMER_M_REG, + ms_media_byte)) + if status: + pass + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_SET_TIMER_H_REG, + ms_high_byte)) + if status: + pass + return self._gettimeout() + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + data = [0, 0, 0] + status, data[0] = self._getstatusoutput(self._i2cget_cmd(I2C_WDT_SET_TIMER_L_REG)) + if status: + pass + status, data[1] = self._getstatusoutput(self._i2cget_cmd(I2C_WDT_SET_TIMER_M_REG)) + if status: + pass + status, data[2] = self._getstatusoutput(self._i2cget_cmd(I2C_WDT_SET_TIMER_H_REG)) + if status: + pass + seconds = int((int(data[2], 16) << 16 + | int(data[1], 16) << 8 + | int(data[0], 16)) / 1000) + + return seconds + + def _settimeleft(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + ms = seconds * 1000 + ms_low_byte = ms & 0xff + ms_media_byte = (ms >> 8) & 0xff + ms_high_byte = (ms >> 16) & 0xff + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_TIMER_L_REG, + ms_low_byte)) + if status: + pass + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_TIMER_M_REG, + ms_media_byte)) + if status: + pass + status, data = self._getstatusoutput(self._i2cset_cmd(I2C_WDT_TIMER_H_REG, + ms_high_byte)) + if status: + pass + + def _gettimeleft(self): + """ + Get time left before watchdog timer expires + @return time left in seconds + """ + data = [0, 0, 0] + status, data[0] = self._getstatusoutput(self._i2cget_cmd(I2C_WDT_TIMER_L_REG)) + if status: + pass + status, data[1] = self._getstatusoutput(self._i2cget_cmd(I2C_WDT_TIMER_M_REG)) + if status: + pass + status, data[2] = self._getstatusoutput(self._i2cget_cmd(I2C_WDT_TIMER_H_REG)) + if status: + pass + seconds = int((int(data[2], 16) << 16 + | int(data[1], 16) << 8 + | int(data[0], 16)) / 1000) + + return (self.timeout - seconds) if (self.timeout > seconds) else -1 + + ################################################################# + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + + ret = WDT_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + if self.armed: + self._keepalive() + else: + self._settimeout(seconds) + self._keepalive() + self._enable() + self.armed = True + ret = self.timeout + except IOError as e: + pass + + return ret + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + disarmed = False + if self.is_armed(): + try: + self._disable() + self.armed = False + disarmed = True + except IOError: + pass + + return disarmed + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + + return self.armed + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + + timeleft = WDT_COMMON_ERROR + + if self.armed: + try: + timeleft = self._gettimeleft() + except IOError: + pass + + return timeleft diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/systemd/platform-modules-questone2.service b/platform/broadcom/sonic-platform-modules-cel/questone2/systemd/platform-modules-questone2.service new file mode 100644 index 0000000000..c6ad69112e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/systemd/platform-modules-questone2.service @@ -0,0 +1,13 @@ +[Unit] +Description=Celestica questone2 platform modules +After=local-fs.target +Before=pmon.service + +[Service] +Type=oneshot +ExecStart=-/etc/init.d/platform-modules-questone2 start +ExecStop=-/etc/init.d/platform-modules-questone2 stop +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/platform_sensors.py new file mode 100755 index 0000000000..559a4315a3 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/platform_sensors.py @@ -0,0 +1,161 @@ +#!/usr/bin/python +# +# Silverstone platform sensors. This script get the sensor data from BMC +# using ipmitool and display them in lm-sensor alike format. +# +# The following data is support: +# 1. Temperature sensors +# 2. PSUs +# 3. Fan Drawers + +import sys +import logging +import subprocess + +IPMI_SDR_CMD = ['/usr/bin/ipmitool', 'sdr', 'elist'] +MAX_NUM_FANS = 4 +MAX_NUM_PSUS = 2 + +SENSOR_NAME = 0 +SENSOR_VAL = 4 + +sensor_dict = {} + +def ipmi_sensor_dump(cmd): + ''' Execute ipmitool command return dump output + exit if any error occur. + ''' + global sensor_dict + sensor_dump = '' + + try: + sensor_dump = subprocess.check_output(IPMI_SDR_CMD, universal_newlines=True) + except subprocess.CalledProcessError as e: + logging.error('Error! Failed to execute: {}'.format(cmd)) + sys.exit(1) + + for line in sensor_dump.splitlines(): + sensor_info = line.split('|') + sensor_dict[sensor_info[SENSOR_NAME].strip()] = sensor_info[SENSOR_VAL].strip() + + return True + +def get_reading_by_name(sensor_name, sdr_elist_dump): + found = '' + + for line in sdr_elist_dump.splitlines(): + line = line.decode() + if sensor_name in line: + found = line.strip() + break + + if not found: + logging.error('Cannot find sensor name:' + sensor_name) + + else: + try: + found = found.split('|')[4] + except IndexError: + logging.error('Cannot get sensor data of:' + sensor_name) + + logging.basicConfig(level=logging.DEBUG) + return found + + +def read_temperature_sensors(): + sensor_list = [\ + ('Base_Temp_U5', 'Baseboard Right Temp'),\ + ('Base_Temp_U7', 'Baseboard Left Temp'),\ + ('Switch_Temp_U1', 'ASIC External Front Temp'),\ + ('Switch_Temp_U18', 'ASIC External Rear Temp'),\ + ('Switch_Temp_U28', 'Switchboard Right Temp'),\ + ('Switch_Temp_U29', 'Switchboard Left Temp'),\ + ('CPU_Temp', 'CPU Internal Temp'),\ + ('Switch_U33_Temp', 'IR3595 Chip Temp'),\ + ('Switch_U21_Temp', 'IR3584 Chip Temp'),\ + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "Temperature Sensors\n" + output += "Adapter: IPMI adapter\n" + for sensor in sensor_list: + output += sensor_format.format('{}:'.format(sensor[1]),\ + sensor_dict[sensor[0]],\ + width=str(max_name_width+1)) + output += '\n' + return output + +def read_fan_sensors(num_fans): + + sensor_list = [\ + ('Fan{}_Status', 'Fan Drawer {} Status'),\ + ('Fan{}_Front', 'Fan {} front'),\ + ('Fan{}_Rear', 'Fan {} rear'),\ + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "Fan Drawers\n" + output += "Adapter: IPMI adapter\n" + for fan_num in range(1, num_fans+1): + for sensor in sensor_list: + ipmi_sensor_name = sensor[0].format(fan_num) + display_sensor_name = sensor[1].format(fan_num) + output += sensor_format.format('{}:'.format(display_sensor_name),\ + sensor_dict[ipmi_sensor_name],\ + width=str(max_name_width+1)) + output += '\n' + return output + +def read_psu_sensors(num_psus): + + sensor_list = [\ + ('PSU{}_Status', 'PSU {} Status'),\ + ('PSU{}_Fan', 'PSU {} Fan 1'),\ + ('PSU{}_VIn', 'PSU {} Input Voltage'),\ + ('PSU{}_CIn', 'PSU {} Input Current'),\ + ('PSU{}_PIn', 'PSU {} Input Power'),\ + ('PSU{}_Temp1', 'PSU {} Ambient Temp'),\ + ('PSU{}_Temp2', 'PSU {} Hotspot Temp'),\ + ('PSU{}_VOut', 'PSU {} Output Voltage'),\ + ('PSU{}_COut', 'PSU {} Output Current'),\ + ('PSU{}_POut', 'PSU {} Output Power'),\ + ] + + output = '' + sensor_format = '{0:{width}}{1}\n' + # Find max length of sensor calling name + max_name_width = max(len(sensor[1]) for sensor in sensor_list) + + output += "PSU\n" + output += "Adapter: IPMI adapter\n" + for psu_num in range(1, num_psus+1): + for sensor in sensor_list: + ipmi_sensor_name = sensor[0].format('L' if psu_num == 1 else 'R') + display_sensor_name = sensor[1].format(psu_num) + output += sensor_format.format('{}:'.format(display_sensor_name),\ + sensor_dict[ipmi_sensor_name],\ + width=str(max_name_width+1)) + output += '\n' + return output + +def main(): + output_string = '' + + if ipmi_sensor_dump(IPMI_SDR_CMD): + output_string += read_temperature_sensors() + output_string += read_psu_sensors(MAX_NUM_PSUS) + output_string += read_fan_sensors(MAX_NUM_FANS) + + print(output_string) + + +if __name__ == '__main__': + main() diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/seastone2_platform_shutdown.sh b/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/seastone2_platform_shutdown.sh new file mode 100755 index 0000000000..e04cac54fa --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/seastone2_platform_shutdown.sh @@ -0,0 +1,26 @@ +#!/bin/bash +REBOOT_CAUSE_DIR="/host/reboot-cause" +HW_REBOOT_CAUSE_FILE="/host/reboot-cause/hw-reboot-cause.txt" +REBOOT_TIME=$(date) + +if [ $# -ne 1 ]; then + echo "Require reboot type" + exit 1 +fi + +if [ ! -d "$REBOOT_CAUSE_DIR" ]; then + mkdir $REBOOT_CAUSE_DIR +fi + +echo "Reason:$1,Time:${REBOOT_TIME}" > ${HW_REBOOT_CAUSE_FILE} + +# Best effort to write buffered data onto the disk +sync ; sync ; sync ; sleep 3 + +# BMC cold power-cyle +ipmitool chassis power cycle &> /dev/null + +# System should reboot by now and avoid the script returning to caller +sleep 10 + +exit 0 \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/sensors b/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/sensors new file mode 100755 index 0000000000..5d740a9eb7 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/scripts/sensors @@ -0,0 +1,11 @@ +#!/bin/bash + +DOCKER_EXEC_FLAGS="i" + +# Determine whether stdout is on a terminal +if [ -t 1 ] ; then + DOCKER_EXEC_FLAGS+="t" +fi + +docker exec -$DOCKER_EXEC_FLAGS pmon sensors "$@" +docker exec -$DOCKER_EXEC_FLAGS pmon python3 /usr/bin/platform_sensors.py "$@" diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/setup.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/setup.py new file mode 100644 index 0000000000..8d253086b2 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/setup.py @@ -0,0 +1,31 @@ +from setuptools import setup + +setup( + name='sonic-platform', + version='1.0', + description='SONiC platform API implementation on Celestica Platforms', + 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', + ], + package_dir={ + 'sonic_platform': 'sonic_platform'}, + 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 :: 3.9', + 'Topic :: Utilities', + ], + keywords='sonic SONiC platform PLATFORM', +) diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/__init__.py new file mode 100644 index 0000000000..d3c24cb008 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import platform diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/chassis.py new file mode 100644 index 0000000000..d18a220a56 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/chassis.py @@ -0,0 +1,436 @@ +#!/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 +# +############################################################################# + +try: + import sys + import time + import os + import re + import shutil + from sonic_platform_base.chassis_base import ChassisBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_DRAWER = 4 +NUM_FAN_PER_DRAWER = 2 +NUM_PSU = 2 +NUM_THERMAL = 13 +NUM_SFP = 33 +NUM_COMPONENT = 9 + +REBOOT_CAUSE_REG = "0xA106" +BASE_CPLD_PLATFORM = "baseboard" +BASE_GETREG_PATH = "/sys/devices/platform/{}/getreg".format(BASE_CPLD_PLATFORM) +IPMI_GET_SYS_STATUS_LED="ipmitool raw 0x3A 0x0C 0x00 0x02 0x62" +IPMI_SET_SYS_STATUS_LED="ipmitool raw 0x3A 0x0C 0x00 0x03 0x62 {}" + +ORG_HW_REBOOT_CAUSE_FILE="/host/reboot-cause/hw-reboot-cause.txt" +TMP_HW_REBOOT_CAUSE_FILE="/tmp/hw-reboot-cause.txt" + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + sfp_status_dict={} + + #led color status + SYSLED_COLOR_VAL_MAP = {\ + 'off': '0x33',\ + 'green': '0x10',\ + 'green_blink_1hz': '0x11',\ + 'amber': '0x20'\ + } + + SYSLED_VAL_COLOR_DESC_MAP = { + 0x33: 'off',\ + 0x10: 'green',\ + 0x11: 'green_blink_1hz',\ + 0x20: 'amber'\ + } + + def __init__(self): + ChassisBase.__init__(self) + self._api_helper = APIHelper() + self.sfp_module_initialized = False + self.fan_module_initialized = False + self._watchdog = None + self._airflow_direction = None + self.__initialize_eeprom() + + self.__initialize_thermals() + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_components() + + def __initialize_sfp(self): + if not self.sfp_module_initialized: + from sonic_platform.sfp import Sfp + for index in range(0, NUM_SFP): + sfp = Sfp(index) + self._sfp_list.append(sfp) + present = sfp.get_presence() + self.sfp_status_dict[sfp.index] = '1' if present else '0' + self.sfp_module_initialized = True + + def __initialize_psu(self): + from sonic_platform.psu import Psu + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + + def __initialize_fan(self): + from sonic_platform.fan import Fan + from sonic_platform.fan_drawer import FanDrawer + for fand_index in range(0, NUM_FAN_DRAWER): + drawer_fan_list=[] + for fan_index in range(0, NUM_FAN_PER_DRAWER): + fan = Fan(fand_index, fan_index) + self._fan_list.append(fan) + drawer_fan_list.append(fan) + fan_drawer = FanDrawer(fand_index, drawer_fan_list) + self._fan_drawer_list.append(fan_drawer) + self.fan_module_initialized = True + + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + def __initialize_eeprom(self): + from sonic_platform.eeprom import Eeprom + self._eeprom = Eeprom() + + def __initialize_components(self): + from sonic_platform.component import Component + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + + def initizalize_system_led(self): + return True + + def get_status_led(self): + color_str = 'N/A' + status, output = self._api_helper.run_command(IPMI_GET_SYS_STATUS_LED) + if status: + color_val = int(output, 16) & 0x33 + color_str = self.SYSLED_VAL_COLOR_DESC_MAP.get(color_val, color_str) + + return color_str + + def set_status_led(self, color): + status = False + + color_val = self.SYSLED_COLOR_VAL_MAP.get(color, None) + if color_val != None: + cmd = IPMI_SET_SYS_STATUS_LED.format(color_val) + status, res = self._api_helper.run_command(cmd) + + return status + + 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' + """ + return self._eeprom.get_mac() + + def get_serial_number(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + hw_reboot_cause = self._api_helper.get_register_value( + BASE_GETREG_PATH, REBOOT_CAUSE_REG) + + + # This tmp copy is to retain the reboot-cause only for the current boot + if os.path.isfile(ORG_HW_REBOOT_CAUSE_FILE): + shutil.move(ORG_HW_REBOOT_CAUSE_FILE, TMP_HW_REBOOT_CAUSE_FILE) + + if hw_reboot_cause == "0x33" and os.path.isfile(TMP_HW_REBOOT_CAUSE_FILE): + with open(TMP_HW_REBOOT_CAUSE_FILE) as hw_cause_file: + reboot_info = hw_cause_file.readline().rstrip('\n') + match = re.search(r'Reason:(.*),Time:(.*)', reboot_info) + if match is not None: + if match.group(1) == 'system': + return (self.REBOOT_CAUSE_NON_HARDWARE, 'System cold reboot') + + + if hw_reboot_cause == "0x99": + reboot_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_ASIC + description = 'ASIC Overload Reboot' + elif hw_reboot_cause == "0x88": + reboot_cause = self.REBOOT_CAUSE_THERMAL_OVERLOAD_CPU + description = 'CPU Overload Reboot' + elif hw_reboot_cause == "0x77": + reboot_cause = self.REBOOT_CAUSE_WATCHDOG + description = 'Hardware Watchdog Reset' + elif hw_reboot_cause == "0x55": + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'CPU Cold Reset' + elif hw_reboot_cause == "0x44": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'CPU Warm Reset' + elif hw_reboot_cause == "0x33": + # When NON_HARDWARE is used and device is powercycled via IPMI + # reboot cause computed as Unknown, Hence using HARDWARE_OTHER + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'Soft-Set Cold Reset' + elif hw_reboot_cause == "0x22": + reboot_cause = self.REBOOT_CAUSE_NON_HARDWARE + description = 'Soft-Set Warm Reset' + elif hw_reboot_cause == "0x11": + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + description = 'Power On Reset' + elif hw_reboot_cause == "0x00": + reboot_cause = self.REBOOT_CAUSE_POWER_LOSS + description = 'Power Cycle Reset' + else: + reboot_cause = self.REBOOT_CAUSE_HARDWARE_OTHER + description = 'Hardware reason' + + return (reboot_cause, description) + + ############################################################## + ######################## SFP methods ######################### + ############################################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + Returns: + An integer, the number of sfps available on this chassis + """ + self.__initialize_sfp() + + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + self.__initialize_sfp() + + return self._sfp_list + + def get_sfp(self, index): + """ + Retrieves sfp represented by (0-based) index + Args: + index: An integer, the index (0-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 0. + For example, 0 for Ethernet1, 1 for Ethernet2 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + sfp = None + self.__initialize_sfp() + + try: + sfp = self._sfp_list[index - 1] + except IndexError: + sys.stderr.write("SFP index {} out of range (0-{})\n".format( + index, len(self._sfp_list) - 1)) + return sfp + + ############################################################## + ####################### Other methods ######################## + ############################################################## + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_helper.hwsku + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._eeprom.get_pn() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self.get_serial_number() + + def get_revision(self): + """ + Retrieves the hardware revision for the chassis + Returns: + A string containing the hardware revision for this chassis. + """ + return self._eeprom.get_revision() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True + + ############################################################## + ###################### Event methods ######################### + ############################################################## + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + + Returns: + (bool, dict): + - bool: True if call successful, False if not; + - dict: A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, where device_id is the device ID + for this device and device_event. + The known devices's device_id and device_event was defined as table below. + ----------------------------------------------------------------- + device | device_id | device_event | annotate + ----------------------------------------------------------------- + 'fan' '' '0' Fan removed + '1' Fan inserted + + 'sfp' '' '0' Sfp removed + '1' Sfp inserted + '2' I2C bus stuck + '3' Bad eeprom + '4' Unsupported cable + '5' High Temperature + '6' Bad cable + + 'voltage' '' '0' Vout normal + '1' Vout abnormal + -------------------------------------------------------------------- + Ex. {'fan':{'0':'0', '2':'1'}, 'sfp':{'11':'0', '12':'1'}, + 'voltage':{'U20':'0', 'U21':'1'}} + Indicates that: + fan 0 has been removed, fan 2 has been inserted. + sfp 11 has been removed, sfp 12 has been inserted. + monitored voltage U20 became normal, voltage U21 became abnormal. + Note: For sfp, when event 3-6 happened, the module will not be avalaible, + XCVRD shall stop to read eeprom before SFP recovered from error status. + """ + sfp_dict = {} + + SFP_REMOVED = '0' + SFP_INSERTED = '1' + + SFP_PRESENT = True + SFP_ABSENT = False + + start_time = time.time() + time_period = timeout/float(1000) #Convert msecs to secs + + while time.time() < (start_time + time_period) or timeout == 0: + for sfp in self._sfp_list: + port_idx = sfp.index + if self.sfp_status_dict[port_idx] == SFP_REMOVED and \ + sfp.get_presence() == SFP_PRESENT: + sfp_dict[port_idx] = SFP_INSERTED + self.sfp_status_dict[port_idx] = SFP_INSERTED + elif self.sfp_status_dict[port_idx] == SFP_INSERTED and \ + sfp.get_presence() == SFP_ABSENT: + sfp_dict[port_idx] = SFP_REMOVED + self.sfp_status_dict[port_idx] = SFP_REMOVED + + if sfp_dict: + return True, {'sfp':sfp_dict} + + time.sleep(0.5) + + return True, {'sfp':{}} # Timeout + + def get_airflow_direction(self): + if self._airflow_direction == None: + try: + vendor_extn = self._eeprom.get_vendor_extn() + airflow_type = vendor_extn.split()[2][2:4] # Either 0xFB or 0xBF + if airflow_type == 'FB': + direction = 'exhaust' + elif airflow_type == 'BF': + direction = 'intake' + else: + direction = 'N/A' + except (AttributeError, IndexError): + direction = 'N/A' + + self._airflow_direction = direction + + return self._airflow_direction diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/component.py new file mode 100644 index 0000000000..1f82f87e67 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/component.py @@ -0,0 +1,156 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +import os.path +import re + +try: + #from sonic_platform_base.component_base import ComponentBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NAME_IDX = 0 +DESC_IDX = 1 +VER_API_IDX = 2 + +BASE_CPLD_PLATFORM = "baseboard" +SW_CPLD_PLATFORM = "switchboard" +PLATFORM_SYSFS_PATH = "/sys/devices/platform/" + +FPGA_GETREG_PATH = "{}/{}/FPGA/getreg".format( + PLATFORM_SYSFS_PATH, SW_CPLD_PLATFORM) +BASE_GETREG_PATH = "{}/{}/getreg".format( + PLATFORM_SYSFS_PATH, BASE_CPLD_PLATFORM) +SW_CPLD1_GETREG_PATH = "{}/{}/CPLD1/getreg".format( + PLATFORM_SYSFS_PATH, SW_CPLD_PLATFORM) +SW_CPLD2_GETREG_PATH = "{}/{}/CPLD2/getreg".format( + PLATFORM_SYSFS_PATH, SW_CPLD_PLATFORM) +BIOS_VER_PATH = "/sys/class/dmi/id/bios_version" + +BASE_CPLD_VER_REG = "0xA100" +COME_CPLD_VER_REG = "0xA1E0" +SW_CPLD_VER_REG = "0x00" +FPGA_VER_REG = "0x00" + +UNKNOWN_VER = "N/A" +ONIE_VER_CMD = "cat /host/machine.conf" +SSD_VER_CMD = "smartctl -i /dev/sda" + +class Component(): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_index): + COMPONENT_LIST = [ + ("BIOS", "Basic input/output System", self.__get_bios_ver), + ("ONIE", "Open Network Install Environment", self.__get_onie_ver), + ("BMC", "Baseboard Management Controller", self.__get_bmc_ver), + ("FPGA", "FPGA for transceiver EEPROM access and other component I2C access", self.__get_fpga_ver), + ("CPLD COMe", "COMe board CPLD", self.__get_cpld_ver), + ("CPLD BASE", "CPLD for board functions, fan control and watchdog", self.__get_cpld_ver), + ("CPLD SW1", "CPLD for port control QSFP(1-16)", self.__get_cpld_ver), + ("CPLD SW2", "CPLD for port control QSFP(17-32) SFP(33)", self.__get_cpld_ver), + ("SSD", "Solid State Drive - {}", self.__get_ssd_ver), + ] + + self.index = component_index + self.name = COMPONENT_LIST[self.index][NAME_IDX] + self.description = COMPONENT_LIST[self.index][DESC_IDX] + self.__get_version = COMPONENT_LIST[self.index][VER_API_IDX] + self._api_helper = APIHelper() + + def __get_bios_ver(self): + return self._api_helper.read_one_line_file(BIOS_VER_PATH) + + def __get_onie_ver(self): + onie_ver = "N/A" + status, raw_onie_data = self._api_helper.run_command(ONIE_VER_CMD) + if status: + ret = re.search(r"(?<=onie_version=).+[^\n]", raw_onie_data) + if ret != None: + onie_ver = ret.group(0) + return onie_ver + + def __get_bmc_ver(self): + cmd="ipmitool mc info | grep 'Firmware Revision'" + status, raw_ver=self._api_helper.run_command(cmd) + if status: + bmc_ver=raw_ver.split(':')[-1].strip() + return bmc_ver + else: + return UNKNOWN_VER + + def __get_fpga_ver(self): + version_raw = self._api_helper.get_register_value(FPGA_GETREG_PATH, FPGA_VER_REG) + return "{}.{}".format(int(version_raw[2:][:4], 16), int(version_raw[2:][4:], 16)) if version_raw else UNKNOWN_VER + + def __get_cpld_ver(self): + cpld_api_param = { + 'CPLD COMe': (BASE_GETREG_PATH, COME_CPLD_VER_REG), + 'CPLD BASE': (BASE_GETREG_PATH, BASE_CPLD_VER_REG), + 'CPLD SW1': (SW_CPLD1_GETREG_PATH, SW_CPLD_VER_REG), + 'CPLD SW2': (SW_CPLD2_GETREG_PATH, SW_CPLD_VER_REG), + } + api_param = cpld_api_param[self.name] + + cpld_ver = self._api_helper.get_register_value(api_param[0], api_param[1]) + return "{}.{}".format(int(cpld_ver[2], 16), int(cpld_ver[3], 16)) if cpld_ver else UNKNOWN_VER + + def __get_ssd_ver(self): + ssd_ver = "N/A" + status, raw_ssd_data = self._api_helper.run_command(SSD_VER_CMD) + if status: + ret = re.search(r"Firmware Version: +(.*)[^\\]", raw_ssd_data) + if ret != None: + ssd_ver = ret.group(1) + return ssd_ver + + def __get_ssd_model(self): + model = "N/A" + + status, raw_ssd_data = self._api_helper.run_command(SSD_VER_CMD) + if status: + ret = re.search(r"Device Model: +(.*)[^\\]", raw_ssd_data) + if ret != None: + try: + model = ret.group(1) + except (IndexError): + pass + return model + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + # For SSD get the model name from device + if self.name == "SSD": + return self.description.format(self.__get_ssd_model()) + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + return self.__get_version() diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/eeprom.py new file mode 100644 index 0000000000..32afdc2751 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/eeprom.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os + import sys + import re + import json + import fcntl + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +NULL = 'N/A' +EEPROM_TMP_FILE = '/tmp/eeprom_dump.json' + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + for i2cbus in range(2): + path_prefix = "/sys/class/i2c-adapter/i2c-{}/".format(i2cbus) + with open(path_prefix + "name") as fd: + if 'SMBus iSMT adapter at ' in fd.readline(): + self._eeprom_path = path_prefix + "{}-0056/eeprom".format(i2cbus) + break + super(Eeprom, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search('(0x[0-9a-fA-F]{2})\s+\d+\s+(.+)', line) + if match is not None: + idx = match.group(1) + value = match.group(2).rstrip('\0') + + _eeprom_info_dict[idx] = value + except Exception: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + eeprom_dict = {} + + if os.path.exists(EEPROM_TMP_FILE): + with open(EEPROM_TMP_FILE, 'r') as fd: + eeprom_dict = json.load(fd) + + return eeprom_dict + + original_stdout = sys.stdout + sys.stdout = StringIO() + rv = -1 + try: + rv = self.read_eeprom_db() + except BaseException: + pass + + if rv == 0: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + eeprom_dict = self.__parse_output(decode_output) + else: + e = self.read_eeprom() + if e is None: + sys.stdout = original_stdout + return {} + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return {} + + eeprom_dict = self.__parse_output(decode_output) + + if len(eeprom_dict) != 0: + with open(EEPROM_TMP_FILE, 'w') as fd: + fcntl.flock(fd, fcntl.LOCK_EX) + json.dump(eeprom_dict, fd) + fcntl.flock(fd, fcntl.LOCK_UN) + + return eeprom_dict + + def get_eeprom(self): + return self._eeprom + + def get_product(self): + return self._eeprom.get('0x21', NULL) + + def get_pn(self): + return self._eeprom.get('0x22', NULL) + + def get_serial(self): + return self._eeprom.get('0x23', NULL) + + def get_mac(self): + return self._eeprom.get('0x24', NULL) + + def get_revision(self): + return self._eeprom.get('0x26', NULL) + + def get_vendor_extn(self): + return self._eeprom.get('0xFD', NULL) diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/fan.py new file mode 100644 index 0000000000..2b577ac402 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/fan.py @@ -0,0 +1,345 @@ +#!/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 +# +############################################################################# + +try: + from sonic_platform_base.fan_base import FanBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NOT_AVAILABLE = 'N/A' + +FAN_NAME_TEMPLATE = "{}Fan{}{}" +NUM_FAN_TRAYS = 4 +NUM_FANS_PER_TRAY = 2 +FAN_SPEED_TOLERANCE = 20 +MAX_RPM_FRONT=23000 +MAX_RPM_REAR=20500 +MAX_RPM_PSU=22600 +FAN_DIR_BASE = 0x41 +FAN_LED_BASE = 0x04 +FAN_FRU_BASE = 0x05 +FAN_STATUS_BASE = 0x00 +FAN_SID_BASE = 0x80 +PSU_FAN_SID_BASE = 0x8a +PSU_FRU_BASE = 0x03 + + +IPMI_FAN_DIR="ipmitool raw 0x3a 0x0c 0x00 0x02 {}" +IPMI_GET_SPEED="ipmitool raw 0x04 0x2d {}" +IPMI_GET_CPLD_PWM="ipmitool raw 0x3a 0x0c 0x00 0x02 {}" +IPMI_GET_PRESENCE="ipmitool raw 0x3a 0x03 0x03 {}" +IPMI_GET_MODEL="ipmitool fru list {} | grep 'Board Part Number'" +IPMI_GET_SERIAL="ipmitool fru list {} | grep 'Board Serial'" +IPMI_GET_PSU_MODEL="ipmitool fru list {} | grep 'Product Name'" +IPMI_GET_PSU_SPEED="ipmitool raw 0x04 0x2d {}" +IPMI_SET_STATUS_LED="ipmitool raw 0x3a 0x0a {} {}" +IPMI_GET_STATUS_LED="ipmitool raw 0x3a 0x0b {}" + +class Fan(FanBase): + """Platform-specific Fan class""" + + def __init__(self, fan_tray_index, fan_index=0, is_psu_fan=False, psu_index=0): + self.fan_index = fan_index + self.fan_tray_index = fan_tray_index + self.is_psu_fan = is_psu_fan + self._api_helper = APIHelper() + self.index = (self.fan_tray_index * 2) + self.fan_index + self.name = None + if self.is_psu_fan: + self.psu_index = psu_index + self.max_speed = MAX_RPM_PSU + self._fan_sid_offset = PSU_FAN_SID_BASE + self.psu_index + self._fan_status_offset = FAN_STATUS_BASE + NUM_FAN_TRAYS + self.psu_index + else: + self._fan_status_offset = FAN_STATUS_BASE + self.fan_tray_index + self._fan_fru_offset = FAN_FRU_BASE + self.fan_tray_index + self._fan_dir_offset = FAN_DIR_BASE + (self.fan_tray_index * 4) + if self.fan_tray_index > 1: + # Questone CPLD firmware is used and hence FAN 3 will be missing + # There are only 4 FAN trays in this platform + self._fan_dir_offset = self._fan_dir_offset + 4 + + self._fan_speed_offset = self._fan_dir_offset - 1 + self._fan_led_offset = FAN_LED_BASE + self.fan_tray_index + + if fan_index % 2 == 0: + # Front FAN + self.is_front = True + self.max_speed = MAX_RPM_FRONT + self._fan_sid_offset = FAN_SID_BASE + 1 + (self.fan_tray_index * NUM_FANS_PER_TRAY) + else: + # Rear FAN + self.is_front = False + self.max_speed = MAX_RPM_REAR + self._fan_sid_offset = FAN_SID_BASE + (self.fan_tray_index * NUM_FANS_PER_TRAY) + + def get_direction(self): + """ + Retrieves the direction of fan + Returns: + A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST + depending on fan direction + """ + direction = NOT_AVAILABLE + + if self.is_psu_fan: + cmd = IPMI_GET_PSU_MODEL.format(PSU_FRU_BASE + self.psu_index) + status, output = self._api_helper.run_command(cmd) + if status and output: + model = output.split(':')[-1] + if len(model) > 0: + if model[-2:] == ' B': + direction = self.FAN_DIRECTION_INTAKE + else: + direction = self.FAN_DIRECTION_EXHAUST + else: + cmd = IPMI_FAN_DIR.format(self._fan_dir_offset) + status, output = self._api_helper.run_command(cmd) + if status: + dir_num = int(output, 16) & 0x0C + if dir_num == 0x0: + direction = self.FAN_DIRECTION_EXHAUST + elif dir_num == 0x8: + direction = self.FAN_DIRECTION_INTAKE + + return direction + + def get_speed(self): + """ + Retrieves the speed of fan as a percentage of full speed + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + """ + speed = 0 + + if not self.is_psu_fan: + multiplier = 150.0 + else: + multiplier = 100.0 + + cmd = IPMI_GET_PSU_SPEED.format(self._fan_sid_offset) + status, output = self._api_helper.run_command(cmd) + if status: + raw_speed = output.split()[0] + rpm_speed = int(raw_speed, 16) * multiplier + speed = int((rpm_speed/self.max_speed) * 100) + + return speed + + def get_target_speed(self): + """ + Retrieves the target (expected) speed of the fan + Returns: + An integer, the percentage of full fan speed, in the range 0 (off) + to 100 (full speed) + + Note: + speed_pc = pwm_target/255*100 + + 0 : when PWM mode is use + pwm : when pwm mode is not use + """ + target_speed = 0 + + if self.is_psu_fan: + # Ignored for tolerance check + return self.get_speed() + + cmd = IPMI_GET_CPLD_PWM.format(self._fan_speed_offset) + status, output = self._api_helper.run_command(cmd) + if status: + fan_pwm = int(output, 16) + target_speed = round(fan_pwm / 255 * 100) + + return target_speed + + 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 FAN_SPEED_TOLERANCE + + def set_speed(self, speed): + """ + Sets the fan speed + Args: + speed: An integer, the percentage of full fan speed to set fan to, + in the range 0 (off) to 100 (full speed) + Returns: + A boolean, True if speed is set successfully, False if not + Notes: + pwm setting mode must set as Manual + manual: systemctl stop fanctrl.service + auto: systemctl start fanctrl.service + """ + + # FAN speed is controlled by BCM always + return False + + def set_status_led(self, color): + """ + Sets the state of the fan module status LED + Args: + color: A string representing the color with which to set the + fan module status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + # There is no per Fan LED + return True + + def drawer_set_status_led(self, color): + status = False + + color_dict = {\ + self.STATUS_LED_COLOR_OFF: 0,\ + self.STATUS_LED_COLOR_AMBER: 1,\ + self.STATUS_LED_COLOR_RED: 1,\ + self.STATUS_LED_COLOR_GREEN: 2\ + } + + if not self.is_psu_fan: + cmd = IPMI_SET_STATUS_LED.format(self._fan_led_offset, color_dict.get(color, 0)) + status, _ = self._api_helper.run_command(cmd) + + return status + + + def get_status_led(self): + """ + Gets the state of the fan status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + + Note: + Output + STATUS_LED_COLOR_GREEN = "green" + STATUS_LED_COLOR_AMBER = "amber" + STATUS_LED_COLOR_RED = "red" + STATUS_LED_COLOR_OFF = "off" + + Input + 0x1: green + 0x2: red + 0x3: off + """ + status = NOT_AVAILABLE + color_dict = {\ + 0: self.STATUS_LED_COLOR_OFF,\ + 1: self.STATUS_LED_COLOR_AMBER,\ + 2: self.STATUS_LED_COLOR_GREEN\ + } + + if not self.is_psu_fan: + cmd = IPMI_GET_STATUS_LED.format(self._fan_led_offset) + status, output = self._api_helper.run_command(cmd) + if status: + color = int(output, 16) + status = color_dict.get(color, status) + + return status + + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + + if not self.name: + if not self.is_psu_fan: + psu_name = "" + fan_id = " {}".format(self.fan_tray_index + 1) + fan_type = " Front" if self.is_front else " Rear" + else: + psu_name = "PSU {} ".format(self.psu_index + 1) + fan_id = " {}".format(self.fan_tray_index + 1) + fan_type = "" + + self.name = FAN_NAME_TEMPLATE.format(psu_name, fan_id, fan_type) + + return self.name + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + + presence = False + + cmd = IPMI_GET_PRESENCE.format(self._fan_status_offset) + status, output = self._api_helper.run_command(cmd) + if status and output == "00": + presence = True + + return presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = NOT_AVAILABLE + + if not self.is_psu_fan: + cmd = IPMI_GET_MODEL.format(self._fan_fru_offset) + status, output = self._api_helper.run_command(cmd) + if status and output: + return output.split()[-1] + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial = NOT_AVAILABLE + + if not self.is_psu_fan: + cmd = IPMI_GET_SERIAL.format(self._fan_fru_offset) + status, output = self._api_helper.run_command(cmd) + if status and output: + return output.split()[-1] + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and self.get_speed() > 0 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + if not self.is_psu_fan: + return True + + return False diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/fan_drawer.py new file mode 100644 index 0000000000..aea952d582 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/fan_drawer.py @@ -0,0 +1,91 @@ +#!/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 +# +############################################################################# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +class FanDrawer(FanDrawerBase): + + def __init__(self, index, fan_list): + FanDrawerBase.__init__(self) + + self._fan_list = fan_list + self._index = index + 1 + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + Args: + color: A string representing the color with which to set the + fan drawer status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return self._fan_list[0].drawer_set_status_led(color) + + def get_status_led(self): + """ + Gets the state of the fan drawer LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._fan_list[0].get_status_led() + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return 'Drawer {}'.format(self._index) + + def get_presence(self): + """ + Retrieves the presence of the FAN + Returns: + bool: True if FAN is present, False if not + """ + return self._fan_list[0].get_presence() + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._fan_list[0].get_model() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._fan_list[0].get_serial() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self._fan_list[0].get_status() + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/helper.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/helper.py new file mode 100644 index 0000000000..3a861cb575 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/helper.py @@ -0,0 +1,210 @@ +#!/usr/bin/env python + +import os +import struct +import subprocess +from mmap import * +from sonic_py_common.device_info import get_platform_and_hwsku + +SCALE = 16 +BIN_BITS = 8 +EMPTY_STRING = "" +HOST_CHK_CMD = "docker > /dev/null 2>&1" + + +class APIHelper(): + + def __init__(self): + (self.platform, self.hwsku) = get_platform_and_hwsku() + + def get_register_value(self, getreg_path, register): + cmd = "echo {1} > {0}; cat {0}".format(getreg_path, register) + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + return raw_data.strip().decode('UTF-8') if not err else None + + def hex_to_bin(self, ini_string): + return bin(int(ini_string, SCALE)).zfill(BIN_BITS) + + def is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except Exception: + status = False + return status, result + + def run_command(self, cmd): + status = True + result = "" + try: + p = subprocess.Popen( + cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err.decode('UTF-8') == '': + result = raw_data.strip().decode('UTF-8') + except Exception: + status = False + return status, result + + def run_interactive_command(self, cmd): + try: + os.system(cmd) + except Exception: + return False + return True + + def read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def read_one_line_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.readline() + return data.strip() + except IOError: + pass + return None + + def search_file_by_contain(self, directory, search_str, file_start): + for dirpath, dirnames, files in os.walk(directory): + for name in files: + file_path = os.path.join(dirpath, name) + if name.startswith(file_start) and search_str in self.read_txt_file(file_path): + return dirpath + return None + + def write_file(self, file_path, data): + try: + with open(file_path, 'w') as fd: + fd.write(str(data)) + return True + except Exception: + pass + return False + + def ipmi_raw(self, netfn, cmd): + status = True + result = "" + try: + cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd)) + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def ipmi_fru_id(self, id, key=None): + status = True + result = "" + try: + cmd = "ipmitool fru print {}".format(str( + id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key)) + + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def ipmi_set_ss_thres(self, id, threshold_key, value): + status = True + result = "" + try: + cmd = "ipmitool sensor thresh '{}' {} {}".format( + str(id), str(threshold_key), str(value)) + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except Exception: + status = False + return status, result + + def fru_decode_product_serial(self, data): + + if data and data[4] != 00: + start_product_info = ord(data[4]) * 8 + start_format_version = start_product_info + start_product_info = start_format_version + 1 + start_product_Lang_code = start_product_info + 1 + start_product_Manu_name = start_product_Lang_code + 1 + start_product_Manu_name_length = ord(data[start_product_Manu_name]) & 0x0F + start_product_name = start_product_Manu_name + start_product_Manu_name_length + 1 + start_product_name_length = ord(data[start_product_name]) & 0x0F + start_product_module_number = start_product_name + start_product_name_length +1 + start_product_module_number_length = ord(data[start_product_module_number]) & 0x0F + start_product_version = start_product_module_number + start_product_module_number_length +1 + start_product_version_length = ord(data[start_product_version]) & 0x0F + start_product_serial_number = start_product_version + start_product_version_length +1 + start_product_serial_number_length = ord(data[start_product_serial_number]) & 0x1F + return data[start_product_serial_number+1:start_product_serial_number+start_product_serial_number_length+1] + return "N/A" + + def fru_decode_product_model(self, data): + if data and data[4] != 00: + start_product_info = ord(data[4]) * 8 + start_format_version = start_product_info + start_product_info = start_format_version + 1 + start_product_lang_code = start_product_info + 1 + start_product_manu_name = start_product_lang_code + 1 + start_product_manu_name_length = ord(data[start_product_manu_name]) & 0x1F + start_product_name = start_product_manu_name + start_product_manu_name_length + 1 + start_product_name_length = ord(data[start_product_name]) & 0x1F + start_product_module_number = start_product_name + start_product_name_length + 1 + start_product_module_number_length = ord(data[start_product_module_number]) & 0x1F + return data[start_product_module_number + 1: start_product_module_number +start_product_module_number_length + 1] + return "N/A" + + def fru_decode_product_name(self, data): + + if data and data[4] != 00: + start_product_info = ord(data[4]) * 8 + start_format_version = start_product_info + start_product_info = start_format_version + 1 + start_product_Lang_code = start_product_info + 1 + start_product_Manu_name = start_product_Lang_code + 1 + start_product_Manu_name_length = ord(data[start_product_Manu_name]) & 0x0F + start_product_name = start_product_Manu_name + start_product_Manu_name_length + 1 + start_product_name_length = ord(data[start_product_name]) & 0x0F + return data[start_product_name+1: start_product_name+start_product_name_length+1] + + return "N/A" + + def read_eeprom_sysfs(self,sys_path,sysfs_file): + sysfs_path = os.path.join(sys_path, sysfs_file) + try: + with open(sysfs_path, mode='rb', buffering=0) as fd: + data = fd.read(256) + return data + except Exception: + pass + return None diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/pcie.py new file mode 100644 index 0000000000..2f7931d42b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/pcie.py @@ -0,0 +1,15 @@ +# +# pcie_base.py +# +# Abstract base class for implementing platform-specific +# PCIE functionality for SONiC +# + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError (str(e) + " - required module not found") + +class Pcie(PcieUtil): + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/platform.py new file mode 100644 index 0000000000..c9ba822ac0 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/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/seastone2/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/psu.py new file mode 100644 index 0000000000..362463883a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/psu.py @@ -0,0 +1,273 @@ +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.psu_base import PsuBase + from .helper import APIHelper + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +IPMI_SENSOR_NETFN = "0x04" +IPMI_SENSOR_READ_CMD = "0x2D {}" +IPMI_SENSOR_THRESH_CMD = "0x27 {}" +IPMI_FRU_MODEL_KEY = "Product Name" +IPMI_FRU_SERIAL_KEY = "Product Serial" + +MAX_PSU_POWER = 550 #Watts +psu_ipmi_id = {\ + 1: {\ + "TEMP": "0x0d",\ + "VOUT": "0x0f",\ + "COUT": "0x10",\ + "POUT": "0x11",\ + "STATUS": "0x72",\ + "FRU": 3,\ + }, + 2: {\ + "TEMP": "0x17",\ + "VOUT": "0x19",\ + "COUT": "0x1a",\ + "POUT": "0x1b",\ + "STATUS": "0x73",\ + "FRU": 4,\ + } +} + +ANALOG_READ_OFFSET = 0 +EVENT_0_7_OFFSET = 2 +EVENT_8_14_OFFSET = 3 + +FRU_SERIAL = 4 +FRU_MODEL = 1 + + +class Psu(PsuBase): + """Platform-specific Psu class""" + + def __init__(self, psu_index): + PsuBase.__init__(self) + self.index = psu_index+1 + # PSU has only one FAN + fan = Fan(0, 0, is_psu_fan=True, psu_index=psu_index) + self._fan_list.append(fan) + self._api_helper = APIHelper() + + def get_voltage(self): + """ + Retrieves current PSU voltage output + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + psu_voltage = 0.0 + psu_vout_key = psu_ipmi_id[self.index]['VOUT'] + status, output = self._api_helper.ipmi_raw(IPMI_SENSOR_NETFN,\ + IPMI_SENSOR_READ_CMD.format(psu_vout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx10^-1 + psu_voltage = int(value, 16) / 10.0 + + return psu_voltage + + def get_voltage_high_threshold(self): + return 12.6 + + def get_voltage_low_threshold(self): + return 11.4 + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + psu_current = 0.0 + psu_cout_key = psu_ipmi_id[self.index]['COUT'] + status, output = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_cout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx3x10^-1 + psu_current = int(value, 16) * 3 / 10.0 + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + Returns: + A float number, the power in watts, e.g. 302.6 + """ + psu_power = 0.0 + psu_pout_key = psu_ipmi_id[self.index]['POUT'] + status, output = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx5 + psu_power = int(value, 16) * 5 + return psu_power + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if self.get_presence(): + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + else: + return "blinking green" + else: + return "N/A" + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + # PSU's ambient temperature sensor is considered as the PSU temperature + psu_temp = 0.0 + psu_temp_id = psu_ipmi_id[self.index]['TEMP'] + status, output = self._api_helper.ipmi_raw(IPMI_SENSOR_NETFN,\ + IPMI_SENSOR_READ_CMD.format(psu_temp_id)) + if status: + value = output.split()[ANALOG_READ_OFFSET] + psu_temp = float(int(value, 16)) + + return psu_temp + + def get_maximum_supplied_power(self): + """ + Retrieves the maximum supplied power by PSU + Returns: + A float number, the maximum power output in Watts. + e.g. 1200.1 + """ + + return MAX_PSU_POWER + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return "PSU {}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + psu_presence = False + psu_pstatus_key = psu_ipmi_id[self.index]['STATUS'] + status, raw_status_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pstatus_key)) + status_byte = raw_status_read.split()[EVENT_0_7_OFFSET] + + if status: + psu_presence = True if int(status_byte, 16) & 0x01 == 0x01 else False + + return psu_presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = "Unknown" + if self.get_presence(): + ipmi_fru_idx = psu_ipmi_id[self.index]['FRU'] + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_MODEL_KEY) + + fru_pn_list = raw_model.split(':')[-1] + model = fru_pn_list.strip() + else: + model = "N/A" + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial = "Unknown" + if self.get_presence(): + ipmi_fru_idx = psu_ipmi_id[self.index]['FRU'] + status, raw_serial = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_SERIAL_KEY) + + fru_sr_list = raw_serial.split(':')[-1] + serial = fru_sr_list.strip() + else: + model = "N/A" + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + psu_status = False + psu_pstatus_key = psu_ipmi_id[self.index]['STATUS'] + status, raw_status_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pstatus_key)) + status_byte = raw_status_read.split()[EVENT_0_7_OFFSET] + + if status: + psu_status = False if int(status_byte, 16) & 0x08 == 0x08 else True + + return psu_status + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True + + def get_direction(self): + """ + Return the airflow direction of PSU FAN + Returns: + string: 'intake' or 'exhaust' + """ + self diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/sfp.py new file mode 100644 index 0000000000..9de0aea627 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/sfp.py @@ -0,0 +1,198 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Sfp contains an implementation of SONiC Platform Base API and +# provides the sfp device status which are available in the platform +# +############################################################################# +import time + +try: + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +SFP_TYPE = "SFP" +QSFP_TYPE = "QSFP" + +QSFP_PORT_START = 1 +QSFP_PORT_END = 32 +SFP_PORT_START = 33 +SFP_PORT_END = 33 + +PORT_INFO_PATH = '/sys/class/seastone2_fpga' +SFP_I2C_START = 2 + + +class Sfp(SfpOptoeBase): + """Platform-specific Sfp class""" + + # Path to QSFP sysfs + PLATFORM_ROOT_PATH = "/usr/share/sonic/device" + PMON_HWSKU_PATH = "/usr/share/sonic/hwsku" + + def __init__(self, sfp_index): + SfpOptoeBase.__init__(self) + # Init index + self.index = sfp_index + 1 + self.sfp_type, self.port_name = self.__get_sfp_info() + self._api_helper = APIHelper() + self.platform = self._api_helper.platform + self.hwsku = self._api_helper.hwsku + + # Init eeprom path + self.eeprom_path = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom'.format(SFP_I2C_START+sfp_index) + + def __get_sfp_info(self): + port_name = "Unknown" + sfp_type = "Unknown" + + if self.index >= QSFP_PORT_START and self.index <= QSFP_PORT_END: + sfp_type = QSFP_TYPE + port_name = sfp_type + str(self.index) + elif self.index >= SFP_PORT_START and self.index <= SFP_PORT_END: + sfp_type = SFP_TYPE + port_name = sfp_type + str(self.index - SFP_PORT_START + 1) + + return sfp_type, port_name + + def __get_path_to_port_config_file(self): + platform_path = "/".join([self.PLATFORM_ROOT_PATH, self.platform]) + hwsku_path = "/".join([platform_path, self.hwsku] + ) if self._api_helper.is_host() else self.PMON_HWSKU_PATH + return "/".join([hwsku_path, "port_config.ini"]) + + def get_eeprom_path(self): + return self.eeprom_path + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reg_status = self._api_helper.read_one_line_file( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_reset"])) + + return (int(reg_status) == 0) + + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + if self.sfp_type != QSFP_TYPE: + return False + + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_reset"]), "w") + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(0)) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register to take port out of reset + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_reset"]), "w") + except IOError as e: + #print("Error: unable to open file: %s" % str(e)) + return False + + reg_file.seek(0) + reg_file.write(hex(1)) + reg_file.close() + + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + + try: + reg_file = open( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_lpmode"]), "w") + except IOError as e: + return False + + if lpmode: + value=1 + else: + value=0 + reg_file.write(hex(value)) + reg_file.close() + + return True + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + + reg_status = self._api_helper.read_one_line_file( + "/".join([PORT_INFO_PATH, self.port_name, "qsfp_lpmode"])) + + return (int(reg_status) == 1) + + def get_position_in_parent(self): + return self.index + + def is_replaceable(self): + return True + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + sfputil_helper = SfpUtilHelper() + sfputil_helper.read_porttab_mappings( + self.__get_path_to_port_config_file()) + name = sfputil_helper.physical_to_logical[self.index] or "Unknown" + return name + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + # Get path for access port presence status + sysfs_filename = "sfp_modabs" if self.sfp_type == SFP_TYPE else "qsfp_modprs" + reg_path = "/".join([PORT_INFO_PATH, self.port_name, sysfs_filename]) + + content = self._api_helper.read_one_line_file(reg_path) + reg_value = int(content) + + return (reg_value == 0) + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() and not self.get_reset_status() diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/thermal.py new file mode 100644 index 0000000000..1db171329a --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/thermal.py @@ -0,0 +1,204 @@ +############################################################################# +# Celestica +# +# Thermal contains an implementation of SONiC Platform Base API and +# provides the thermal device status which are available in the platform +# +############################################################################# + +import os +import re +import os.path + +try: + from sonic_platform_base.thermal_base import ThermalBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +IPMI_SENSOR_NETFN = "0x04" +IPMI_SS_READ_CMD = "0x2D {}" +IPMI_SS_THRESHOLD_CMD = "0x27 {}" +HIGH_TRESHOLD_SET_KEY = "unc" +DEFAULT_VAL = 'N/A' + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + def __init__(self, thermal_index): + ThermalBase.__init__(self) + self._api_helper = APIHelper() + self.index = thermal_index + thermal_list = [\ + ('Base_Temp_U5', '0x01', 'Baseboard Right Temp'),\ + ('Base_Temp_U7', '0x02', 'Baseboard Left Temp'),\ + ('Switch_Temp_U1', '0x03', 'ASIC External Front Temp'),\ + ('Switch_Temp_U18', '0x04', 'ASIC External Rear Temp'),\ + ('Switch_Temp_U28', '0x05', 'Switchboard Right Temp'),\ + ('Switch_Temp_U29', '0x06', 'Switchboard Left Temp'),\ + ('CPU_Temp', '0x07', 'CPU Internal Temp'),\ + ('Switch_U33_Temp', '0x4C', 'IR3595 Chip Temp'),\ + ('Switch_U21_Temp', '0x56', 'IR3584 Chip Temp'),\ + ('PSUL_Temp1', '0x0D', 'PSU 1 Ambient Temp'),\ + ('PSUL_Temp2', '0x0E', 'PSU 1 Hotspot Temp'),\ + ('PSUR_Temp1', '0x17', 'PSU 2 Ambient Temp'),\ + ('PSUR_Temp2', '0x18', 'PSU 2 Hotspot Temp'),\ + ] + self.sensor_id = thermal_list[self.index][0] + self.sensor_reading_addr = thermal_list[self.index][1] + self.sensor_name = thermal_list[self.index][2] + + temp = self.get_temperature(True) + self.minimum_thermal = temp + self.maximum_thermal = temp + + def get_temperature(self, skip_record=False): + """ + Retrieves current temperature reading from thermal + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + status, raw_ss_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(self.sensor_reading_addr)) + if status and len(raw_ss_read.split()) > 0: + ss_read = raw_ss_read.split()[0] + temperature = float(int(ss_read, 16)) + + if temperature != 0.0: + if not skip_record: + # Record maximum + if temperature > self.maximum_thermal: + self.maximum_thermal = temperature + + # Record minimum + if temperature < self.minimum_thermal: + self.minimum_thermal = temperature + + return temperature + else: + return DEFAULT_VAL + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + high_threshold = 0.0 + status, raw_up_thres_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_THRESHOLD_CMD.format(self.sensor_reading_addr)) + if status and len(raw_up_thres_read.split()) > 6: + ss_read = raw_up_thres_read.split()[4] + high_threshold = float(int(ss_read, 16)) + if high_threshold != 0.0: + return high_threshold + else: + return DEFAULT_VAL + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return DEFAULT_VAL + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if not + """ + status, ret_txt = self._api_helper.ipmi_set_ss_thres( + self.sensor_id, HIGH_TRESHOLD_SET_KEY, temperature) + return status + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if not + """ + return False + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + high_critical_threshold = 0.0 + status, raw_up_thres_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_THRESHOLD_CMD.format(self.sensor_reading_addr)) + if status and len(raw_up_thres_read.split()) > 6: + ss_read = raw_up_thres_read.split()[5] + high_critical_threshold = float(int(ss_read, 16)) + if high_critical_threshold != 0.0: + return high_critical_threshold + else: + return DEFAULT_VAL + + def get_minimum_recorded(self): + """ + Retrieves the minimum recorded temperature of thermal + Returns: + A float number, the minimum recorded temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self.minimum_thermal + + def get_maximum_recorded(self): + """ + Retrieves the maximum recorded temperature of thermal + Returns: + A float number, the maximum recorded temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self.maximum_thermal + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the thermal device + Returns: + string: The name of the thermal device + """ + return self.sensor_name + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return True if self.get_temperature() > 0 else False + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + + def is_replaceable(self): + """ + Retrieves whether thermal module is replaceable + Returns: + A boolean value, True if replaceable, False if not + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/watchdog.py new file mode 100644 index 0000000000..2290119674 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/seastone2/sonic_platform/watchdog.py @@ -0,0 +1,274 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica Seastone2 +# +# Watchdog contains an implementation of SONiC Platform Base API +# +############################################################################# +import subprocess +import syslog +import fcntl + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +PLATFORM_CPLD_PATH = '/sys/devices/platform/baseboard/{}' +I2C_WDT_ARM_REG='0xA181' +I2C_WDT_SET_TIMER_L_REG='0xA182' +I2C_WDT_SET_TIMER_M_REG='0xA183' +I2C_WDT_SET_TIMER_H_REG='0xA184' +I2C_WDT_KEEPALIVE_REG='0xA185' +I2C_WDT_TIMER_L_REG='0xA186' +I2C_WDT_TIMER_M_REG='0xA187' +I2C_WDT_TIMER_H_REG='0xA188' + +WDT_ENABLE=0x1 +WDT_DISABLE=0x0 +WDT_KEEPALIVE=0x1 +WDT_COMMON_ERROR=-1 +DEFAULT_TIMEOUT=180 + +class Watchdog(WatchdogBase): + + def __init__(self): + # Set default value + self.armed = True if self._is_active() else False + self.timeout = self._gettimeout() + #self._disable() + + def _get_lpc_reg(self, reg): + file_path = PLATFORM_CPLD_PATH.format('getreg') + value = None + status = False + + try: + fd = open(file_path, "w+") + # Acquire an exclusive lock on the file + fcntl.flock(fd, fcntl.LOCK_EX) + fd.write(reg) + fd.flush() + fd.seek(0) + value = fd.readline().rstrip() + status = True + except (IOError, PermissionError, FileNotFoundError): + syslog.syslog(syslog.LOG_ERR, "Baseboard LPC getreg failed with {}",format(e)) + value = None + status = False + finally: + fcntl.flock(fd, fcntl.LOCK_UN) + fd.close() + + return status, value + + def _set_lpc_reg(self, reg, val): + status = False + file_path = PLATFORM_CPLD_PATH.format('setreg') + value = '{} {}'.format(reg, hex(val)) + + try: + fd = open(file_path, 'w') + fcntl.flock(fd, fcntl.LOCK_EX) + fd.write(value) + status = True + except (IOError, PermissionError, FileNotFoundError): + syslog.syslog(syslog.LOG_ERR, "Baseboard LPC setreg failed with {}",format(e)) + value = None + status = False + finally: + fcntl.flock(fd, fcntl.LOCK_UN) + fd.close() + + return status + + def _is_active(self): + """ + WDT is active or not + """ + status, data = self._get_lpc_reg(I2C_WDT_ARM_REG) + if status and data == "0x01": + return True + + return False + + def _enable(self): + """ + Turn on the watchdog timer + """ + self._settimeleft(0) + return self._set_lpc_reg(I2C_WDT_ARM_REG, WDT_ENABLE) + + def _disable(self): + """ + Turn off the watchdog timer + """ + return self._set_lpc_reg(I2C_WDT_ARM_REG, WDT_DISABLE) + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + self._settimeleft(0) + return self._set_lpc_reg(I2C_WDT_KEEPALIVE_REG, WDT_KEEPALIVE) + + def _settimeout(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + ms = seconds * 1000 + ms_low_byte = ms & 0xff + ms_media_byte = (ms >> 8) & 0xff + ms_high_byte = (ms >> 16) & 0xff + self._set_lpc_reg(I2C_WDT_SET_TIMER_L_REG, ms_low_byte) + self._set_lpc_reg(I2C_WDT_SET_TIMER_M_REG, ms_media_byte) + self._set_lpc_reg(I2C_WDT_SET_TIMER_H_REG, ms_high_byte) + + return self._gettimeout() + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + data = [0, 0, 0] + status, data[0] = self._get_lpc_reg(I2C_WDT_SET_TIMER_L_REG) + if not status: + return 0 + status, data[1] = self._get_lpc_reg(I2C_WDT_SET_TIMER_M_REG) + if not status: + return 0 + status, data[2] = self._get_lpc_reg(I2C_WDT_SET_TIMER_H_REG) + if not status: + return 0 + seconds = int((int(data[2], 16) << 16 + | int(data[1], 16) << 8 + | int(data[0], 16)) / 1000) + + return seconds + + def _settimeleft(self, seconds): + """ + Set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + ms = seconds * 1000 + ms_low_byte = ms & 0xff + ms_media_byte = (ms >> 8) & 0xff + ms_high_byte = (ms >> 16) & 0xff + self._set_lpc_reg(I2C_WDT_TIMER_L_REG, ms_low_byte) + self._set_lpc_reg(I2C_WDT_TIMER_M_REG, ms_media_byte) + self._set_lpc_reg(I2C_WDT_TIMER_H_REG, ms_high_byte) + + return True + + def _gettimeleft(self): + """ + Get time left before watchdog timer expires + @return time left in seconds + """ + data = [0, 0, 0] + status, data[0] = self._get_lpc_reg(I2C_WDT_TIMER_L_REG) + if not status: + return 0 + status, data[1] = self._get_lpc_reg(I2C_WDT_TIMER_M_REG) + if not status: + return 0 + status, data[2] = self._get_lpc_reg(I2C_WDT_TIMER_H_REG) + if not status: + return 0 + seconds = int((int(data[2], 16) << 16 + | int(data[1], 16) << 8 + | int(data[0], 16)) / 1000) + + return (self.timeout - seconds) if (self.timeout > seconds) else 0 + + ################################################################# + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + + ret = WDT_COMMON_ERROR + if seconds < 0: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + if self.armed: + self._keepalive() + else: + status = self._enable() + if not status: + syslog.syslog(syslog.LOG_ERR, "Enable watchdog failed") + return ret + + self.armed = True + + ret = self.timeout + except IOError: + pass + + return ret + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + disarmed = False + if self.is_armed(): + try: + status = self._disable() + if status: + self.armed = False + disarmed = True + else: + syslog.syslog(syslog.LOG_ERR, "Disable watchdog failed") + except IOError: + pass + + return disarmed + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + + return self.armed + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Returns: + An integer specifying the number of seconds remaining on thei + watchdog timer. If the watchdog is not armed, returns -1. + """ + + timeleft = WDT_COMMON_ERROR + + if self.armed: + try: + timeleft = self._gettimeleft() + except IOError: + pass + + return timeleft diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf b/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf index cb8dcf640b..0015389458 100644 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/cfg/silverstone-modules.conf @@ -9,7 +9,7 @@ i2c-ismt i2c-dev i2c-mux i2c-smbus +coretemp -i2c-mux-pca954x ipmi_devintf -ipmi_si \ No newline at end of file +ipmi_si diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile index f6ad4d9ba4..44b9b6147e 100644 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/Makefile @@ -1 +1 @@ -obj-m := baseboard-lpc.o mc24lc64t.o switchboard.o \ No newline at end of file +obj-m := baseboard-lpc.o mc24lc64t.o cls-switchboard.o xcvr-cls.o switch_cpld.o cls-i2c-mux-pca954x.o diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c index b6291f7d3c..50f9e2d886 100644 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/baseboard-lpc.c @@ -98,7 +98,7 @@ static ssize_t version_show(struct device *dev, struct device_attribute *attr, c mutex_lock(&cpld_data->cpld_lock); version = inb(VERSION_ADDR); mutex_unlock(&cpld_data->cpld_lock); - return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); + return sprintf(buf, "%x.%x\n", version >> 4, version & 0x0F); } static DEVICE_ATTR_RO(version); @@ -430,4 +430,4 @@ module_exit(cpld_b_exit); MODULE_AUTHOR("Celestica Inc."); MODULE_DESCRIPTION("Celestica Silverstone CPLD baseboard driver"); MODULE_VERSION("0.2.0"); -MODULE_LICENSE("GPL"); \ No newline at end of file +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-i2c-mux-pca954x.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-i2c-mux-pca954x.c new file mode 100644 index 0000000000..71b635f326 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-i2c-mux-pca954x.c @@ -0,0 +1,579 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * I2C multiplexer + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * + * This module supports the PCA954x and PCA984x series of I2C multiplexer/switch + * chips made by NXP Semiconductors. + * This includes the: + * PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547, + * PCA9548, PCA9846, PCA9847, PCA9848 and PCA9849. + * + * These chips are all controlled via the I2C bus itself, and all have a + * single 8-bit register. The upstream "parent" bus fans out to two, + * four, or eight downstream busses or channels; which of these + * are selected is determined by the chip type and register contents. A + * mux can select only one sub-bus at a time; a switch can select any + * combination simultaneously. + * + * Based on: + * pca954x.c from Kumar Gala + * Copyright (C) 2006 + * + * Based on: + * pca954x.c from Ken Harrenstien + * Copyright (C) 2004 Google, Inc. (Ken Harrenstien) + * + * Based on: + * i2c-virtual_cb.c from Brian Kuschak + * and + * pca9540.c from Jean Delvare . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cls-pca954x.h" + +#define PCA954X_MAX_NCHANS 8 + +#define PCA954X_IRQ_OFFSET 4 + +enum pca_type { + pca_9540, + pca_9542, + pca_9543, + pca_9544, + pca_9545, + pca_9546, + pca_9547, + pca_9548, + pca_9846, + pca_9847, + pca_9848, + pca_9849, +}; + +struct chip_desc { + u8 nchans; + u8 enable; /* used for muxes only */ + u8 has_irq; + enum muxtype { + pca954x_ismux = 0, + pca954x_isswi + } muxtype; + struct i2c_device_identity id; +}; + +struct pca954x { + const struct chip_desc *chip; + + u8 last_chan; /* last register value */ + /* MUX_IDLE_AS_IS, MUX_IDLE_DISCONNECT or >= 0 for channel */ + s32 idle_state; + + struct i2c_client *client; + + struct irq_domain *irq; + unsigned int irq_mask; + raw_spinlock_t lock; +}; + +/* Provide specs for the PCA954x types we know about */ +static const struct chip_desc chips[] = { + [pca_9540] = { + .nchans = 2, + .enable = 0x4, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9542] = { + .nchans = 2, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9543] = { + .nchans = 2, + .has_irq = 1, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9544] = { + .nchans = 4, + .enable = 0x4, + .has_irq = 1, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9545] = { + .nchans = 4, + .has_irq = 1, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9546] = { + .nchans = 4, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9547] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9548] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .id = { .manufacturer_id = I2C_DEVICE_ID_NONE }, + }, + [pca_9846] = { + .nchans = 4, + .muxtype = pca954x_isswi, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x10b, + }, + }, + [pca_9847] = { + .nchans = 8, + .enable = 0x8, + .muxtype = pca954x_ismux, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x108, + }, + }, + [pca_9848] = { + .nchans = 8, + .muxtype = pca954x_isswi, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x10a, + }, + }, + [pca_9849] = { + .nchans = 4, + .enable = 0x4, + .muxtype = pca954x_ismux, + .id = { + .manufacturer_id = I2C_DEVICE_ID_NXP_SEMICONDUCTORS, + .part_id = 0x109, + }, + }, +}; + +static const struct i2c_device_id pca954x_id[] = { + { "cls_pca9540", pca_9540 }, + { "cls_pca9542", pca_9542 }, + { "cls_pca9543", pca_9543 }, + { "cls_pca9544", pca_9544 }, + { "cls_pca9545", pca_9545 }, + { "cls_pca9546", pca_9546 }, + { "cls_pca9547", pca_9547 }, + { "cls_pca9548", pca_9548 }, + { "cls_pca9846", pca_9846 }, + { "cls_pca9847", pca_9847 }, + { "cls_pca9848", pca_9848 }, + { "cls_pca9849", pca_9849 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, pca954x_id); + +static const struct of_device_id pca954x_of_match[] = { + { .compatible = "nxp,cls_pca9540", .data = &chips[pca_9540] }, + { .compatible = "nxp,cls_pca9542", .data = &chips[pca_9542] }, + { .compatible = "nxp,cls_pca9543", .data = &chips[pca_9543] }, + { .compatible = "nxp,cls_pca9544", .data = &chips[pca_9544] }, + { .compatible = "nxp,cls_pca9545", .data = &chips[pca_9545] }, + { .compatible = "nxp,cls_pca9546", .data = &chips[pca_9546] }, + { .compatible = "nxp,cls_pca9547", .data = &chips[pca_9547] }, + { .compatible = "nxp,cls_pca9548", .data = &chips[pca_9548] }, + { .compatible = "nxp,cls_pca9846", .data = &chips[pca_9846] }, + { .compatible = "nxp,cls_pca9847", .data = &chips[pca_9847] }, + { .compatible = "nxp,cls_pca9848", .data = &chips[pca_9848] }, + { .compatible = "nxp,cls_pca9849", .data = &chips[pca_9849] }, + {} +}; +MODULE_DEVICE_TABLE(of, pca954x_of_match); + +/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer() + for this as they will try to lock adapter a second time */ +static int pca954x_reg_write(struct i2c_adapter *adap, + struct i2c_client *client, u8 val) +{ + union i2c_smbus_data dummy; + + return __i2c_smbus_xfer(adap, client->addr, client->flags, + I2C_SMBUS_WRITE, val, + I2C_SMBUS_BYTE, &dummy); +} + +static u8 pca954x_regval(struct pca954x *data, u8 chan) +{ + /* We make switches look like muxes, not sure how to be smarter. */ + if (data->chip->muxtype == pca954x_ismux) + return chan | data->chip->enable; + else + return 1 << chan; +} + +static int pca954x_select_chan(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + u8 regval; + int ret = 0; + + regval = pca954x_regval(data, chan); + /* Only select the channel if its different from the last channel */ + if (data->last_chan != regval) { + ret = pca954x_reg_write(muxc->parent, client, regval); + data->last_chan = ret < 0 ? 0 : regval; + } + + return ret; +} + +static int pca954x_deselect_mux(struct i2c_mux_core *muxc, u32 chan) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + s32 idle_state; + + idle_state = READ_ONCE(data->idle_state); + if (idle_state >= 0) + /* Set the mux back to a predetermined channel */ + return pca954x_select_chan(muxc, idle_state); + + if (idle_state == MUX_IDLE_DISCONNECT) { + /* Deselect active channel */ + data->last_chan = 0; + return pca954x_reg_write(muxc->parent, client, + data->last_chan); + } + + /* otherwise leave as-is */ + + return 0; +} + +static ssize_t idle_state_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + + return sprintf(buf, "%d\n", READ_ONCE(data->idle_state)); +} + +static ssize_t idle_state_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + int val; + int ret; + + ret = kstrtoint(buf, 0, &val); + if (ret < 0) + return ret; + + if (val != MUX_IDLE_AS_IS && val != MUX_IDLE_DISCONNECT && + (val < 0 || val >= data->chip->nchans)) + return -EINVAL; + + i2c_lock_bus(muxc->parent, I2C_LOCK_SEGMENT); + + WRITE_ONCE(data->idle_state, val); + /* + * Set the mux into a state consistent with the new + * idle_state. + */ + if (data->last_chan || val != MUX_IDLE_DISCONNECT) + ret = pca954x_deselect_mux(muxc, 0); + + i2c_unlock_bus(muxc->parent, I2C_LOCK_SEGMENT); + + return ret < 0 ? ret : count; +} + +static DEVICE_ATTR_RW(idle_state); + +static irqreturn_t pca954x_irq_handler(int irq, void *dev_id) +{ + struct pca954x *data = dev_id; + unsigned long pending; + int ret, i; + + ret = i2c_smbus_read_byte(data->client); + if (ret < 0) + return IRQ_NONE; + + pending = (ret >> PCA954X_IRQ_OFFSET) & (BIT(data->chip->nchans) - 1); + for_each_set_bit(i, &pending, data->chip->nchans) + handle_nested_irq(irq_linear_revmap(data->irq, i)); + + return IRQ_RETVAL(pending); +} + +static int pca954x_irq_set_type(struct irq_data *idata, unsigned int type) +{ + if ((type & IRQ_TYPE_SENSE_MASK) != IRQ_TYPE_LEVEL_LOW) + return -EINVAL; + return 0; +} + +static struct irq_chip pca954x_irq_chip = { + .name = "i2c-mux-pca954x", + .irq_set_type = pca954x_irq_set_type, +}; + +static int pca954x_irq_setup(struct i2c_mux_core *muxc) +{ + struct pca954x *data = i2c_mux_priv(muxc); + struct i2c_client *client = data->client; + int c, irq; + + if (!data->chip->has_irq || client->irq <= 0) + return 0; + + raw_spin_lock_init(&data->lock); + + data->irq = irq_domain_add_linear(client->dev.of_node, + data->chip->nchans, + &irq_domain_simple_ops, data); + if (!data->irq) + return -ENODEV; + + for (c = 0; c < data->chip->nchans; c++) { + irq = irq_create_mapping(data->irq, c); + if (!irq) { + dev_err(&client->dev, "failed irq create map\n"); + return -EINVAL; + } + irq_set_chip_data(irq, data); + irq_set_chip_and_handler(irq, &pca954x_irq_chip, + handle_simple_irq); + } + + return 0; +} + +static void pca954x_cleanup(struct i2c_mux_core *muxc) +{ + struct pca954x *data = i2c_mux_priv(muxc); + int c, irq; + + if (data->irq) { + for (c = 0; c < data->chip->nchans; c++) { + irq = irq_find_mapping(data->irq, c); + irq_dispose_mapping(irq); + } + irq_domain_remove(data->irq); + } + i2c_mux_del_adapters(muxc); +} + +static int pca954x_init(struct i2c_client *client, struct pca954x *data) +{ + int ret; + + if (data->idle_state >= 0) + data->last_chan = pca954x_regval(data, data->idle_state); + else + data->last_chan = 0; /* Disconnect multiplexer */ + + ret = i2c_smbus_write_byte(client, data->last_chan); + if (ret < 0) + data->last_chan = 0; + + return ret; +} + +/* + * I2C init/probing/exit functions + */ +static int pca954x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct i2c_adapter *adap = client->adapter; + struct pca954x_platform_data *pdata = dev_get_platdata(&client->dev); + struct device *dev = &client->dev; + struct gpio_desc *gpio; + struct i2c_mux_core *muxc; + struct pca954x *data; + int num, force; + int ret; + + if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE)) + return -ENODEV; + + muxc = i2c_mux_alloc(adap, dev, PCA954X_MAX_NCHANS, sizeof(*data), 0, + pca954x_select_chan, pca954x_deselect_mux); + if (!muxc) + return -ENOMEM; + data = i2c_mux_priv(muxc); + + i2c_set_clientdata(client, muxc); + data->client = client; + + /* Reset the mux if a reset GPIO is specified. */ + gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(gpio)) + return PTR_ERR(gpio); + if (gpio) { + udelay(1); + gpiod_set_value_cansleep(gpio, 0); + /* Give the chip some time to recover. */ + udelay(1); + } + + data->chip = device_get_match_data(dev); + if (!data->chip) + data->chip = &chips[id->driver_data]; + + if (data->chip->id.manufacturer_id != I2C_DEVICE_ID_NONE) { + struct i2c_device_identity id; + + ret = i2c_get_device_id(client, &id); + if (ret && ret != -EOPNOTSUPP) + return ret; + + if (!ret && + (id.manufacturer_id != data->chip->id.manufacturer_id || + id.part_id != data->chip->id.part_id)) { + dev_warn(dev, "unexpected device id %03x-%03x-%x\n", + id.manufacturer_id, id.part_id, + id.die_revision); + return -ENODEV; + } + } + + data->idle_state = MUX_IDLE_AS_IS; + if (device_property_read_u32(dev, "idle-state", &data->idle_state)) { + if (device_property_read_bool(dev, "i2c-mux-idle-disconnect")) + data->idle_state = MUX_IDLE_DISCONNECT; + } + + /* + * Write the mux register at addr to verify + * that the mux is in fact present. This also + * initializes the mux to a channel + * or disconnected state. + */ + ret = pca954x_init(client, data); + if (ret < 0) { + dev_warn(dev, "probe failed\n"); + return -ENODEV; + } + + ret = pca954x_irq_setup(muxc); + if (ret) + goto fail_cleanup; + + /* Now create an adapter for each channel */ + for (num = 0; num < data->chip->nchans; num++) { + force = 0; /* dynamic adap number */ + if (pdata) { + if (num < pdata->num_modes) { + /* force static number */ + force = pdata->modes[num].adap_id; + } else + /* discard unconfigured channels */ + break; + } + + ret = i2c_mux_add_adapter(muxc, force, num, 0); + if (ret) + goto fail_cleanup; + } + + if (data->irq) { + ret = devm_request_threaded_irq(dev, data->client->irq, + NULL, pca954x_irq_handler, + IRQF_ONESHOT | IRQF_SHARED, + "pca954x", data); + if (ret) + goto fail_cleanup; + } + + /* + * The attr probably isn't going to be needed in most cases, + * so don't fail completely on error. + */ + device_create_file(dev, &dev_attr_idle_state); + + dev_info(dev, "registered %d multiplexed busses for I2C %s %s\n", + num, data->chip->muxtype == pca954x_ismux + ? "mux" : "switch", client->name); + + return 0; + +fail_cleanup: + pca954x_cleanup(muxc); + return ret; +} + +static int pca954x_remove(struct i2c_client *client) +{ + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + + device_remove_file(&client->dev, &dev_attr_idle_state); + + pca954x_cleanup(muxc); + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int pca954x_resume(struct device *dev) +{ + struct i2c_client *client = to_i2c_client(dev); + struct i2c_mux_core *muxc = i2c_get_clientdata(client); + struct pca954x *data = i2c_mux_priv(muxc); + int ret; + + ret = pca954x_init(client, data); + if (ret < 0) + dev_err(&client->dev, "failed to verify mux presence\n"); + + return ret; +} +#endif + +static SIMPLE_DEV_PM_OPS(pca954x_pm, NULL, pca954x_resume); + +static struct i2c_driver pca954x_driver = { + .driver = { + .name = "cls_pca954x", + .pm = &pca954x_pm, + .of_match_table = pca954x_of_match, + }, + .probe = pca954x_probe, + .remove = pca954x_remove, + .id_table = pca954x_id, +}; + +module_i2c_driver(pca954x_driver); + +MODULE_AUTHOR("Rodolfo Giometti "); +MODULE_DESCRIPTION("PCA954x I2C mux/switch driver"); +MODULE_LICENSE("GPL v2"); diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-pca954x.h b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-pca954x.h new file mode 100644 index 0000000000..2aaacf97cb --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-pca954x.h @@ -0,0 +1,44 @@ +/* + * + * cls-pca954x.h - I2C multiplexer/switch support + * + * Copyright (c) 2008-2009 Rodolfo Giometti + * Copyright (c) 2008-2009 Eurotech S.p.A. + * Michael Lawnick + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + + +#ifndef _CLS_I2C_PCA954X_H +#define _CLS_I2C_PCA954X_H + +/* Platform data for the PCA954x I2C multiplexers */ + +/* Per channel initialisation data: + * @adap_id: bus number for the adapter. 0 = don't care + * + */ +struct pca954x_platform_mode { + int adap_id; +}; + +/* Per mux/switch data, used with i2c_register_board_info */ +struct pca954x_platform_data { + struct pca954x_platform_mode *modes; + int num_modes; +}; + +#endif /* _CLS_I2C_PCA954X_H */ diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-switchboard.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-switchboard.c new file mode 100644 index 0000000000..c395c05d2f --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-switchboard.c @@ -0,0 +1,542 @@ +/* + * cls-switchboard.c - PCI device driver for Silverstone Switch board FPGA. + * + * Author: Pradchaya Phucharoen + * + * Copyright (C) 2019 Celestica Corp. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xcvr-cls.h" +#include "cls-pca954x.h" + +#define MOD_VERSION "2.1.2" +#define DRV_NAME "cls-switchboard" + +#define I2C_MUX_CHANNEL(_ch, _adap_id) \ + [_ch] = { .adap_id = _adap_id } + +#define FPGA_PCIE_DEVICE_ID 0x7021 +#define MMIO_BAR 0 +#define I2C_BUS_OFS 9 + +/* I2C ocore configurations */ +#define OCORE_REGSHIFT 2 +#define OCORE_IP_CLK_khz 62500 +#define OCORE_BUS_CLK_khz 100 +#define OCORE_REG_IO_WIDTH 1 + +/* Optical port xcvr configuration */ +#define XCVR_REG_SHIFT 2 +#define XCVR_NUM_PORT 34 +#define XCVR_PORT_REG_SIZE 0x10 + +/* i2c_bus_config - an i2c-core resource and platform data + * @id - I2C bus device ID, for identification. + * @res - resources for an i2c-core device. + * @num_res - size of the resources. + * @pdata - a platform data of an i2c-core device. + */ +struct i2c_bus_config { + int id; + struct resource *res; + ssize_t num_res; + struct ocores_i2c_platform_data pdata; +}; + +/* switchbrd_priv - switchboard private data */ +struct switchbrd_priv { + unsigned long base; + int num_i2c_bus; + struct platform_device **i2cbuses_pdev; + struct platform_device *regio_pdev; + struct platform_device *spiflash_pdev; + struct platform_device *xcvr_pdev; +}; + +/* I2C bus speed param */ +static int bus_clock_master_1 = 100; +module_param(bus_clock_master_1, int, 0660); +MODULE_PARM_DESC(bus_clock_master_1, + "I2C master 1 bus speed in KHz 50/80/100/200/400"); + +static int bus_clock_master_2 = 100; +module_param(bus_clock_master_2, int, 0660); +MODULE_PARM_DESC(bus_clock_master_2, + "I2C master 2 bus speed in KHz 50/80/100/200/400"); + +static int bus_clock_master_3 = 100; +module_param(bus_clock_master_3, int, 0660); +MODULE_PARM_DESC(bus_clock_master_3, + "I2C master 3 bus speed in KHz 50/80/100/200/400"); + +static int bus_clock_master_4 = 100; +module_param(bus_clock_master_4, int, 0660); +MODULE_PARM_DESC(bus_clock_master_4, + "I2C master 4 bus speed in KHz 50/80/100/200/400"); + +static int bus_clock_master_5 = 100; +module_param(bus_clock_master_5, int, 0660); +MODULE_PARM_DESC(bus_clock_master_5, + "I2C master 5 bus speed in KHz 50/80/100/200/400"); + +// NOTE: Silverstone i2c channel mapping is very wierd!!! +/* PCA9548 channel config on MASTER BUS 3 */ +static struct pca954x_platform_mode i2c_mux_70_modes[] = { + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 23), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 26), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 27), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 28), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 29), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 30), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 31), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 32) +}; + +static struct pca954x_platform_mode i2c_mux_71_modes[] = { + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 1), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 2), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 3), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 4), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 5), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 6), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 15), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 8) +}; + +static struct pca954x_platform_mode i2c_mux_72_modes[] = { + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 17), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 18), + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 19), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 20), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 21), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 22), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 25), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 24) +}; + +static struct pca954x_platform_mode i2c_mux_73_modes[] = { + I2C_MUX_CHANNEL(4, I2C_BUS_OFS + 9), + I2C_MUX_CHANNEL(3, I2C_BUS_OFS + 10), + I2C_MUX_CHANNEL(6, I2C_BUS_OFS + 11), + I2C_MUX_CHANNEL(2, I2C_BUS_OFS + 12), + I2C_MUX_CHANNEL(1, I2C_BUS_OFS + 13), + I2C_MUX_CHANNEL(5, I2C_BUS_OFS + 14), + I2C_MUX_CHANNEL(7, I2C_BUS_OFS + 7), + I2C_MUX_CHANNEL(0, I2C_BUS_OFS + 16) +}; + +static struct pca954x_platform_data om_muxes[] = { + { + .modes = i2c_mux_70_modes, + .num_modes = ARRAY_SIZE(i2c_mux_70_modes), + }, + { + .modes = i2c_mux_71_modes, + .num_modes = ARRAY_SIZE(i2c_mux_71_modes), + }, + { + .modes = i2c_mux_72_modes, + .num_modes = ARRAY_SIZE(i2c_mux_72_modes), + }, + { + .modes = i2c_mux_73_modes, + .num_modes = ARRAY_SIZE(i2c_mux_73_modes), + }, +}; + +/* Optical Module bus 3 i2c muxes info */ +static struct i2c_board_info i2c_info_3[] = { + { + I2C_BOARD_INFO("cls_pca9548", 0x70), + .platform_data = &om_muxes[0], + }, + { + I2C_BOARD_INFO("cls_pca9548", 0x71), + .platform_data = &om_muxes[1], + }, + { + I2C_BOARD_INFO("cls_pca9548", 0x72), + .platform_data = &om_muxes[2], + }, + { + I2C_BOARD_INFO("cls_pca9548", 0x73), + .platform_data = &om_muxes[3], + }, +}; + +/* RESOURCE SEPERATES BY FUNCTION */ +/* Resource IOMEM for i2c bus 1 */ +static struct resource cls_i2c_res_1[] = { + { + .start = 0x800, .end = 0x81F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 2 */ +static struct resource cls_i2c_res_2[] = { + { + .start = 0x820, .end = 0x83F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 3 */ +static struct resource cls_i2c_res_3[] = { + { + .start = 0x840, .end = 0x85F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 4 */ +static struct resource cls_i2c_res_4[] = { + { + .start = 0x860, .end = 0x87F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for i2c bus 5 */ +static struct resource cls_i2c_res_5[] = { + { + .start = 0x880, .end = 0x89F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for reg access */ +static struct resource reg_io_res[] = { + { + .start = 0x00, .end = 0xFF, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for spi flash firmware upgrade */ +static struct resource spi_flash_res[] = { + { + .start = 0x1200, .end = 0x121F, + .flags = IORESOURCE_MEM,}, +}; + +/* Resource IOMEM for front panel XCVR */ +static struct resource xcvr_res[] = { + { + .start = 0x4000, .end = 0x421F, + .flags = IORESOURCE_MEM,}, +}; + +static struct i2c_bus_config i2c_bus_configs[] = { + { + .id = 1, + .res = cls_i2c_res_1, + .num_res = ARRAY_SIZE(cls_i2c_res_1), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 2, + .res = cls_i2c_res_2, + .num_res = ARRAY_SIZE(cls_i2c_res_2), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 3, + .res = cls_i2c_res_3, + .num_res = ARRAY_SIZE(cls_i2c_res_3), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = ARRAY_SIZE(i2c_info_3), + .devices = i2c_info_3, + }, + }, + { + .id = 4, + .res = cls_i2c_res_4, + .num_res = ARRAY_SIZE(cls_i2c_res_4), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, + { + .id = 5, + .res = cls_i2c_res_5, + .num_res = ARRAY_SIZE(cls_i2c_res_5), + .pdata = { + .reg_shift = OCORE_REGSHIFT, + .reg_io_width = OCORE_REG_IO_WIDTH, + .clock_khz = OCORE_IP_CLK_khz, + .bus_khz = OCORE_BUS_CLK_khz, + .big_endian = false, + .num_devices = 0, + .devices = NULL, + }, + }, +}; + +/* xcvr front panel mapping */ +static struct port_info front_panel_ports[] = { + {"QSFP1", 1, QSFP}, + {"QSFP2", 2, QSFP}, + {"QSFP3", 3, QSFP}, + {"QSFP4", 4, QSFP}, + {"QSFP5", 5, QSFP}, + {"QSFP6", 6, QSFP}, + {"QSFP7", 7, QSFP}, + {"QSFP8", 8, QSFP}, + {"QSFP9", 9, QSFP}, + {"QSFP10", 10, QSFP}, + {"QSFP11", 11, QSFP}, + {"QSFP12", 12, QSFP}, + {"QSFP13", 13, QSFP}, + {"QSFP14", 14, QSFP}, + {"QSFP15", 15, QSFP}, + {"QSFP16", 16, QSFP}, + {"QSFP17", 17, QSFP}, + {"QSFP18", 18, QSFP}, + {"QSFP19", 19, QSFP}, + {"QSFP20", 20, QSFP}, + {"QSFP21", 21, QSFP}, + {"QSFP22", 22, QSFP}, + {"QSFP23", 23, QSFP}, + {"QSFP24", 24, QSFP}, + {"QSFP25", 25, QSFP}, + {"QSFP26", 26, QSFP}, + {"QSFP27", 27, QSFP}, + {"QSFP28", 28, QSFP}, + {"QSFP29", 29, QSFP}, + {"QSFP30", 30, QSFP}, + {"QSFP31", 31, QSFP}, + {"QSFP32", 32, QSFP}, + {"SFP1", 33, SFP}, + {"SFP2", 34, SFP} + /* END OF LIST */ +}; + +static struct cls_xcvr_platform_data xcvr_data = { + .port_reg_size = 0x10, + .num_ports = ARRAY_SIZE(front_panel_ports), + .devices = front_panel_ports, +}; + + +// TODO: Add a platform configuration struct, and use probe as a factory, +// so xcvr, fwupgrade device can configured as options. + +static int cls_fpga_probe(struct pci_dev *dev, const struct pci_device_id *id) +{ + + struct switchbrd_priv *priv; + struct platform_device **i2cbuses_pdev; + struct platform_device *regio_pdev; + struct platform_device *xcvr_pdev; + unsigned long rstart; + int num_i2c_bus, i; + int err; + + err = pci_enable_device(dev); + if (err){ + dev_err(&dev->dev, "Failed to enable PCI device\n"); + goto err_exit; + } + + /* Check for valid MMIO address */ + rstart = pci_resource_start(dev, MMIO_BAR); + if (!rstart) { + dev_err(&dev->dev, "Switchboard base address uninitialized, " + "check FPGA\n"); + err = -ENODEV; + goto err_disable_device; + } + + dev_dbg(&dev->dev, "BAR%d res: 0x%lx-0x%llx\n", MMIO_BAR, + rstart, pci_resource_end(dev, MMIO_BAR)); + + priv = devm_kzalloc(&dev->dev, + sizeof(struct switchbrd_priv), GFP_KERNEL); + if (!priv){ + err = -ENOMEM; + goto err_disable_device; + } + + pci_set_drvdata(dev, priv); + num_i2c_bus = ARRAY_SIZE(i2c_bus_configs); + i2cbuses_pdev = devm_kzalloc( + &dev->dev, + num_i2c_bus * sizeof(struct platform_device*), + GFP_KERNEL); + + reg_io_res[0].start += rstart; + reg_io_res[0].end += rstart; + + xcvr_res[0].start += rstart; + xcvr_res[0].end += rstart; + + regio_pdev = platform_device_register_resndata( + &dev->dev, "cls-swbrd-io", + -1, + reg_io_res, ARRAY_SIZE(reg_io_res), + NULL, 0); + + if (IS_ERR(regio_pdev)) { + dev_err(&dev->dev, "Failed to register cls-swbrd-io\n"); + err = PTR_ERR(regio_pdev); + goto err_disable_device; + } + + xcvr_pdev = platform_device_register_resndata( + NULL, + "cls-xcvr", + -1, + xcvr_res, + ARRAY_SIZE(xcvr_res), + &xcvr_data, + sizeof(xcvr_data)); + + if (IS_ERR(xcvr_pdev)) { + dev_err(&dev->dev, "Failed to register xcvr node\n"); + err = PTR_ERR(xcvr_pdev); + goto err_unregister_regio; + } + + for(i = 0; i < num_i2c_bus; i++){ + + i2c_bus_configs[i].res[0].start += rstart; + i2c_bus_configs[i].res[0].end += rstart; + + switch (i + 1) { + case 1: + i2c_bus_configs[i].pdata.bus_khz = bus_clock_master_1; + break; + case 2: + i2c_bus_configs[i].pdata.bus_khz = bus_clock_master_2; + break; + case 3: + i2c_bus_configs[i].pdata.bus_khz = bus_clock_master_3; + break; + case 4: + i2c_bus_configs[i].pdata.bus_khz = bus_clock_master_4; + break; + case 5: + i2c_bus_configs[i].pdata.bus_khz = bus_clock_master_5; + break; + default: + i2c_bus_configs[i].pdata.bus_khz = OCORE_BUS_CLK_khz; + } + + dev_dbg(&dev->dev, "i2c-bus.%d: 0x%llx - 0x%llx\n", + i2c_bus_configs[i].id, + i2c_bus_configs[i].res[0].start, + i2c_bus_configs[i].res[0].end); + + i2cbuses_pdev[i] = platform_device_register_resndata( + &dev->dev, "ocores-i2c", + i2c_bus_configs[i].id, + i2c_bus_configs[i].res, + i2c_bus_configs[i].num_res, + &i2c_bus_configs[i].pdata, + sizeof(i2c_bus_configs[i].pdata)); + + if (IS_ERR(i2cbuses_pdev[i])) { + dev_err(&dev->dev, "Failed to register ocores-i2c.%d\n", + i2c_bus_configs[i].id); + err = PTR_ERR(i2cbuses_pdev[i]); + goto err_unregister_ocore; + } + } + + priv->base = rstart; + priv->num_i2c_bus = num_i2c_bus; + priv->i2cbuses_pdev = i2cbuses_pdev; + priv->regio_pdev = regio_pdev; + priv->xcvr_pdev = xcvr_pdev; + return 0; + +err_unregister_ocore: + for(i = 0; i < num_i2c_bus; i++){ + if(priv->i2cbuses_pdev[i]){ + platform_device_unregister(priv->i2cbuses_pdev[i]); + } + } +err_unregister_xcvr: + platform_device_unregister(xcvr_pdev); +err_unregister_regio: + platform_device_unregister(regio_pdev); +err_disable_device: + pci_disable_device(dev); +err_exit: + return err; +} + +static void cls_fpga_remove(struct pci_dev *dev) +{ + int i; + struct switchbrd_priv *priv = pci_get_drvdata(dev); + + for(i = 0; i < priv->num_i2c_bus; i++){ + if(priv->i2cbuses_pdev[i]) + platform_device_unregister(priv->i2cbuses_pdev[i]); + } + platform_device_unregister(priv->xcvr_pdev); + platform_device_unregister(priv->regio_pdev); + pci_disable_device(dev); + return; +}; + +static const struct pci_device_id pci_clsswbrd[] = { + { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, + {0, } +}; + +MODULE_DEVICE_TABLE(pci, pci_clsswbrd); + +static struct pci_driver clsswbrd_pci_driver = { + .name = DRV_NAME, + .id_table = pci_clsswbrd, + .probe = cls_fpga_probe, + .remove = cls_fpga_remove, +}; + +module_pci_driver(clsswbrd_pci_driver); + +MODULE_AUTHOR("Pradchaya P."); +MODULE_DESCRIPTION("Celestica Silverstone switchboard driver"); +MODULE_VERSION(MOD_VERSION); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switch_cpld.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switch_cpld.c new file mode 100644 index 0000000000..7a0abc27e5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switch_cpld.c @@ -0,0 +1,417 @@ +/* + * switch_cpld.c - i2c driver for Silverstone switchboard CPLD1/CPLD2 + * provides sysfs interfaces to access CPLD register and control port LEDs + * + * Author: Budsakol Sirirattanasakul + * + * Copyright (C) 2019 Celestica Corp. + * + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include + +#define CPLD1_ADDR 0x30 +#define CPLD2_ADDR 0x31 + +#define SCRATCH_ADDR 0x01 +#define LED_OPMODE 0x09 +#define LED_TEST 0x0A + +struct switch_cpld_data { + struct mutex lock; + struct i2c_client *client; + struct i2c_client *client2; + uint8_t read_addr; +}; + +static ssize_t getreg_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct switch_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int value; + + value = i2c_smbus_read_byte_data(client, data->read_addr); + if (value < 0) + return value; + + return sprintf(buf, "0x%.2x\n", value); +} + +static ssize_t getreg_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + uint8_t value; + ssize_t status; + struct switch_cpld_data *data = dev_get_drvdata(dev); + + status = kstrtou8(buf, 0, &value); + if (status != 0) + return status; + + data->read_addr = value; + + return size; +} + +static ssize_t setreg_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + uint8_t addr, value; + ssize_t status; + struct switch_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + char *tok; + + tok = strsep((char **)&buf, " "); + if (tok == NULL) + return -EINVAL; + status = kstrtou8(tok, 0, &addr); + if (status != 0) + return status; + + tok = strsep((char **)&buf, " "); + if (tok == NULL) + return -EINVAL; + status = kstrtou8(tok, 0, &value); + if (status != 0) + return status; + + status = i2c_smbus_write_byte_data(client, addr, value); + if (status == 0) + status = size; + return status; +} + +static ssize_t scratch_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct switch_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + int value; + + value = i2c_smbus_read_byte_data(client, SCRATCH_ADDR); + if (value < 0) + return value; + + return sprintf(buf, "0x%.2x\n", value); +} + +static ssize_t scratch_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t size) +{ + uint8_t value; + ssize_t status; + struct switch_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client = data->client; + + status = kstrtou8(buf, 0, &value); + if (status != 0) + return status; + status = i2c_smbus_write_byte_data(client, SCRATCH_ADDR, value); + if (status == 0) + status = size; + return status; +} + +DEVICE_ATTR_RW(getreg); +DEVICE_ATTR_WO(setreg); +DEVICE_ATTR_RW(scratch); + +static struct attribute *switch_cpld_attrs[] = { + &dev_attr_getreg.attr, + &dev_attr_setreg.attr, + &dev_attr_scratch.attr, + NULL, +}; +ATTRIBUTE_GROUPS(switch_cpld); + +static ssize_t port_led_mode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int led_mode_1, led_mode_2; + struct switch_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client1 = data->client; + struct i2c_client *client2 = data->client2; + + led_mode_1 = i2c_smbus_read_byte_data(client1, LED_OPMODE); + if (led_mode_1 < 0) + return led_mode_1; + + led_mode_2 = i2c_smbus_read_byte_data(client2, LED_OPMODE); + if (led_mode_2 < 0) + return led_mode_2; + + return sprintf(buf, "%s %s\n", + led_mode_1 ? "test" : "normal", + led_mode_2 ? "test" : "normal"); +} + +static ssize_t port_led_mode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int status; + uint8_t led_mode; + struct switch_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client1 = data->client; + struct i2c_client *client2 = data->client2; + + if (sysfs_streq(buf, "test")) + led_mode = 0x01; + else if (sysfs_streq(buf, "normal")) + led_mode = 0x00; + else + return -EINVAL; + + status = i2c_smbus_write_byte_data(client1, LED_OPMODE, led_mode); + if (status != 0) { + return status; + } + + status = i2c_smbus_write_byte_data(client2, LED_OPMODE, led_mode); + if (status != 0) { + return status; + } + + return size; +} + +static ssize_t port_led_color_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int led_color1, led_color2; + struct switch_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client1 = data->client; + struct i2c_client *client2 = data->client2; + + led_color1 = i2c_smbus_read_byte_data(client1, LED_TEST); + if (led_color1 < 0) + return led_color1; + + led_color2 = i2c_smbus_read_byte_data(client2, LED_TEST); + if (led_color2 < 0) + return led_color2; + + return sprintf(buf, "%s %s\n", + led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? + "red" : led_color1 == 0x04 ? + "yellow" : led_color1 == 0x03 ? "blue" : led_color1 == 0x02 ? "cyan" : + led_color1 == 0x01 ? "magenta" : "white", + led_color2 == 0x07 ? "off" : led_color2 == 0x06 ? "green" : led_color2 == 0x05 ? + "red" : led_color2 == 0x04 ? + "yellow" : led_color2 == 0x03 ? "blue" : led_color2 == 0x02 ? "cyan" : + led_color2 == 0x01 ? "magenta" : "white"); +} + +static ssize_t port_led_color_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + int status; + uint8_t led_color; + struct switch_cpld_data *data = dev_get_drvdata(dev); + struct i2c_client *client1 = data->client; + struct i2c_client *client2 = data->client2; + + if (sysfs_streq(buf, "off")) + led_color = 0x07; + else if (sysfs_streq(buf, "green")) + led_color = 0x06; + else if (sysfs_streq(buf, "red")) + led_color = 0x05; + else if (sysfs_streq(buf, "yellow")) + led_color = 0x04; + else if (sysfs_streq(buf, "blue")) + led_color = 0x03; + else if (sysfs_streq(buf, "cyan")) + led_color = 0x02; + else if (sysfs_streq(buf, "magenta")) + led_color = 0x01; + else if (sysfs_streq(buf, "white")) + led_color = 0x00; + else + return -EINVAL; + + status = i2c_smbus_write_byte_data(client1, LED_TEST, led_color); + if (status != 0) { + return status; + } + + status = i2c_smbus_write_byte_data(client2, LED_TEST, led_color); + if (status != 0) { + return status; + } + + return size; +} + +DEVICE_ATTR_RW(port_led_mode); +DEVICE_ATTR_RW(port_led_color); + +static struct attribute *sff_led_attrs[] = { + &dev_attr_port_led_mode.attr, + &dev_attr_port_led_color.attr, + NULL, +}; + +static struct attribute_group sff_led_groups = { + .attrs = sff_led_attrs, +}; + +static int switch_cpld_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int err; + struct switch_cpld_data *drvdata1, *drvdata2; + struct device *hwmon_dev1, *hwmon_dev2; + struct i2c_client *client2; + + if (client->addr != CPLD1_ADDR) { + dev_err(&client->dev, "probe, bad i2c addr: 0x%x\n", + client->addr); + err = -EINVAL; + goto exit; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) + return -EPFNOSUPPORT; + + /* CPLD1 */ + drvdata1 = devm_kzalloc(&client->dev, + sizeof(struct switch_cpld_data), GFP_KERNEL); + + if (!drvdata1) { + err = -ENOMEM; + goto exit; + } + + mutex_init(&drvdata1->lock); + drvdata1->client = client; + drvdata1->read_addr = 0x00; + i2c_set_clientdata(client, drvdata1); + hwmon_dev1 = devm_hwmon_device_register_with_groups(&client->dev, + "CPLD1", + drvdata1, + switch_cpld_groups); + + if (IS_ERR(hwmon_dev1)) { + err = PTR_ERR(hwmon_dev1); + goto exit; + } + + err = sysfs_create_link(&client->dev.kobj, &hwmon_dev1->kobj, "CPLD1"); + if (err) { + goto exit; + } + + /* CPLD2 */ + drvdata2 = devm_kzalloc(&client->dev, + sizeof(struct switch_cpld_data), GFP_KERNEL); + + if (!drvdata2) { + err = -ENOMEM; + goto err_link; + } + + client2 = i2c_new_dummy_device(client->adapter, CPLD2_ADDR); + if (!client2) { + dev_err(&client->dev, "address 0x%02x unavailable\n", + CPLD2_ADDR); + err = -EADDRINUSE; + goto err_link; + } + + mutex_init(&drvdata2->lock); + drvdata2->read_addr = 0x00; + drvdata2->client = client2; + i2c_set_clientdata(client2, drvdata2); + + /* attach client2 to be client2 of CPLD1 + for later use on port led sysfs */ + drvdata1->client2 = client2; + + hwmon_dev2 = devm_hwmon_device_register_with_groups(&client2->dev, + "CPLD2", + drvdata2, + switch_cpld_groups); + + if (IS_ERR(hwmon_dev2)) { + err = PTR_ERR(hwmon_dev2); + goto err_client2; + } + + err = sysfs_create_link(&client2->dev.kobj, &hwmon_dev2->kobj, "CPLD2"); + if (err) { + goto err_client2; + } + + //port led + err = sysfs_create_group(&client->dev.kobj, &sff_led_groups); + if (err) { + dev_err(&client->dev, + "failed to create sysfs attribute group.\n"); + goto err_link2; + } + + return 0; + +err_link2: + sysfs_remove_link(&client2->dev.kobj, "CPLD2"); + +err_client2: + if (client2) + i2c_unregister_device(client2); + +err_link: + sysfs_remove_link(&client->dev.kobj, "CPLD1"); + +exit: + dev_err(&client->dev, "probe error %d\n", err); + return err; +} + +static int switch_cpld_remove(struct i2c_client *client) +{ + struct switch_cpld_data *data = i2c_get_clientdata(client); + + sysfs_remove_group(&client->dev.kobj, &sff_led_groups); + sysfs_remove_link(&data->client2->dev.kobj, "CPLD2"); + sysfs_remove_link(&client->dev.kobj, "CPLD1"); + i2c_unregister_device(data->client2); + return 0; +} + +static const struct i2c_device_id switch_cpld_ids[] = { + { "switch_cpld", 0x30 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, switch_cpld_ids); + +static struct i2c_driver switch_cpld_driver = { + .driver = { + .name = "switch_cpld", + .owner = THIS_MODULE, + }, + .probe = switch_cpld_probe, + .remove = switch_cpld_remove, + .id_table = switch_cpld_ids, +}; + +module_i2c_driver(switch_cpld_driver); + +MODULE_AUTHOR("Budsakol Sirirattanasakul"); +MODULE_DESCRIPTION("Celestica Silverstone Switchboard CPLD driver"); +MODULE_VERSION("1.0.0"); +MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c deleted file mode 100644 index e41b64bade..0000000000 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switchboard.c +++ /dev/null @@ -1,2106 +0,0 @@ -/* - * switchboard.c - driver for Silverstone Switch board FPGA/CPLD. - * - * Author: Pradchaya Phucharoen - * - * Copyright (C) 2018 Celestica Corp. - * - * 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * / - * \--sys - * \--devices - * \--platform - * \--silverstone - * |--FPGA - * |--CPLD1 - * |--CPLD2 - * \--SFF - * |--QSFP[1..32] - * \--SFP[1..2] - * - */ - -#ifndef TEST_MODE -#define MOD_VERSION "1.2.0" -#else -#define MOD_VERSION "TEST" -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int majorNumber; - -#define CLASS_NAME "silverstone_fpga" -#define DRIVER_NAME "switchboard" -#define FPGA_PCI_NAME "Silverstone_fpga_pci" -#define DEVICE_NAME "fwupgrade" - - -static int smbus_access(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data); - -static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data); - -static int fpgafw_init(void); -static void fpgafw_exit(void); - - -/* -======================================== -FPGA PCIe BAR 0 Registers -======================================== -Misc Control 0x00000000 – 0x000000FF. -I2C_CH1 0x00000100 - 0x00000110 -I2C_CH2 0x00000200 - 0x00000210. -I2C_CH3 0x00000300 - 0x00000310. -I2C_CH4 0x00000400 - 0x00000410. -I2C_CH5 0x00000500 - 0x00000510. -I2C_CH6 0x00000600 - 0x00000610. -I2C_CH7 0x00000700 - 0x00000710. -I2C_CH8 0x00000800 - 0x00000810. -I2C_CH9 0x00000900 - 0x00000910. -I2C_CH10 0x00000A00 - 0x00000A10. -I2C_CH11 0x00000B00 - 0x00000B10. -I2C_CH12 0x00000C00 - 0x00000C10. -I2C_CH13 0x00000D00 - 0x00000D10. -SPI Master 0x00001200 - 0x00001300. -DPLL SPI Master 0x00001320 - 0x0000132F. -PORT XCVR 0x00004000 - 0x00004FFF. -*/ - -/* MISC */ -#define FPGA_VERSION 0x0000 -#define FPGA_VERSION_MJ_MSK 0xff00 -#define FPGA_VERSION_MN_MSK 0x00ff -#define FPGA_SCRATCH 0x0004 -#define FPGA_BROAD_TYPE 0x0008 -#define FPGA_BROAD_REV_MSK 0x0038 -#define FPGA_BROAD_ID_MSK 0x0007 -#define FPGA_PLL_STATUS 0x0014 -#define BMC_I2C_SCRATCH 0x0020 -#define FPGA_SLAVE_CPLD_REST 0x0030 -#define FPGA_PERIPH_RESET_CTRL 0x0034 -#define FPGA_INT_STATUS 0x0040 -#define FPGA_INT_SRC_STATUS 0x0044 -#define FPGA_INT_FLAG 0x0048 -#define FPGA_INT_MASK 0x004c -#define FPGA_MISC_CTRL 0x0050 -#define FPGA_MISC_STATUS 0x0054 -#define FPGA_AVS_VID_STATUS 0x0068 -#define FPGA_PORT_XCVR_READY 0x000c - -/* I2C_MASTER BASE ADDR */ -#define I2C_MASTER_FREQ_1 0x0100 -#define I2C_MASTER_CTRL_1 0x0104 -#define I2C_MASTER_STATUS_1 0x0108 -#define I2C_MASTER_DATA_1 0x010c -#define I2C_MASTER_PORT_ID_1 0x0110 -#define I2C_MASTER_CH_1 1 -#define I2C_MASTER_CH_2 2 -#define I2C_MASTER_CH_3 3 -#define I2C_MASTER_CH_4 4 -#define I2C_MASTER_CH_5 5 -#define I2C_MASTER_CH_6 6 -#define I2C_MASTER_CH_7 7 -#define I2C_MASTER_CH_8 8 -#define I2C_MASTER_CH_9 9 -#define I2C_MASTER_CH_10 10 -#define I2C_MASTER_CH_11 11 -#define I2C_MASTER_CH_12 12 -#define I2C_MASTER_CH_13 13 - -#define I2C_MASTER_CH_TOTAL I2C_MASTER_CH_5 - -/* SPI_MASTER */ -#define SPI_MASTER_WR_EN 0x1200 /* one bit */ -#define SPI_MASTER_WR_DATA 0x1204 /* 32 bits */ -#define SPI_MASTER_CHK_ID 0x1208 /* one bit */ -#define SPI_MASTER_VERIFY 0x120c /* one bit */ -#define SPI_MASTER_STATUS 0x1210 /* 15 bits */ -#define SPI_MASTER_MODULE_RST 0x1214 /* one bit */ - -/* FPGA FRONT PANEL PORT MGMT */ -#define SFF_PORT_CTRL_BASE 0x4000 -#define SFF_PORT_STATUS_BASE 0x4004 -#define SFF_PORT_INT_STATUS_BASE 0x4008 -#define SFF_PORT_INT_MASK_BASE 0x400c - -#define PORT_XCVR_REGISTER_SIZE 0x1000 - -/* PORT CTRL REGISTER -[31:7] RSVD -[6] LPMOD 6 -[5] RSVD -[4] RST 4 -[3:1] RSVD -[0] TXDIS 0 -*/ -#define CTRL_LPMOD 6 -#define CTRL_RST 4 -#define CTRL_TXDIS 0 - -/* PORT STATUS REGISTER -[31:6] RSVD -[5] IRQ 5 -[4] PRESENT 4 -[3] RSVD -[2] TXFAULT 2 -[1] RXLOS 1 -[0] MODABS 0 -*/ -#define STAT_IRQ 5 -#define STAT_PRESENT 4 -#define STAT_TXFAULT 2 -#define STAT_RXLOS 1 -#define STAT_MODABS 0 - -/* PORT INTRPT REGISTER -[31:6] RSVD -[5] INT_N 5 -[4] PRESENT 4 -[3] RSVD -[2] RSVD -[1] RXLOS 1 -[0] MODABS 0 -*/ -#define INTR_INT_N 5 -#define INTR_PRESENT 4 -#define INTR_TXFAULT 2 -#define INTR_RXLOS 1 -#define INTR_MODABS 0 - -/* PORT INT MASK REGISTER -[31:6] RSVD -[5] INT_N 5 -[4] PRESENT 4 -[3] RSVD -[2] RSVD -[1] RXLOS_INT 1 -[0] MODABS 0 -*/ -#define MASK_INT_N 5 -#define MASK_PRESENT 4 -#define MASK_TXFAULT 2 -#define MASK_RXLOS 1 -#define MASK_MODABS 0 - -enum { - I2C_SR_BIT_RXAK = 0, - I2C_SR_BIT_MIF, - I2C_SR_BIT_SRW, - I2C_SR_BIT_BCSTM, - I2C_SR_BIT_MAL, - I2C_SR_BIT_MBB, - I2C_SR_BIT_MAAS, - I2C_SR_BIT_MCF -}; - -enum { - I2C_CR_BIT_BCST = 0, - I2C_CR_BIT_RSTA = 2, - I2C_CR_BIT_TXAK, - I2C_CR_BIT_MTX, - I2C_CR_BIT_MSTA, - I2C_CR_BIT_MIEN, - I2C_CR_BIT_MEN, -}; - -/** - * - * The function is i2c algorithm implement to allow master access to - * correct endpoint devices trough the PCA9548 switch devices. - * - * FPGA I2C Master [mutex resource] - * | - * | - * --------------------------- - * | PCA9548(s) | - * ---1--2--3--4--5--6--7--8-- - * | | | | | | | | - * EEPROM ... EEPROM - * - */ - -#define VIRTUAL_I2C_QSFP_PORT 32 -#define VIRTUAL_I2C_SFP_PORT 2 - -#define SFF_PORT_TOTAL VIRTUAL_I2C_QSFP_PORT + VIRTUAL_I2C_SFP_PORT - -#define VIRTUAL_I2C_BUS_OFFSET 10 -#define CPLD1_SLAVE_ADDR 0x30 -#define CPLD2_SLAVE_ADDR 0x31 - -static struct class* fpgafwclass = NULL; // < The device-driver class struct pointer -static struct device* fpgafwdev = NULL; // < The device-driver device struct pointer - -#define PCI_VENDOR_ID_TEST 0x1af4 - -#ifndef PCI_VENDOR_ID_XILINX -#define PCI_VENDOR_ID_XILINX 0x10EE -#endif - -#define FPGA_PCIE_DEVICE_ID 0x7021 -#define TEST_PCIE_DEVICE_ID 0x1110 - - -#ifdef DEBUG_KERN -#define info(fmt,args...) printk(KERN_INFO "line %3d : "fmt,__LINE__,##args) -#define check(REG) printk(KERN_INFO "line %3d : %-8s = %2.2X",__LINE__,#REG,ioread8(REG)); -#else -#define info(fmt,args...) -#define check(REG) -#endif - -#define GET_REG_BIT(REG,BIT) ((ioread8(REG) >> BIT) & 0x01) -#define SET_REG_BIT_H(REG,BIT) iowrite8(ioread8(REG) | (0x01 << BIT),REG) -#define SET_REG_BIT_L(REG,BIT) iowrite8(ioread8(REG) & ~(0x01 << BIT),REG) - -static struct mutex fpga_i2c_master_locks[I2C_MASTER_CH_TOTAL]; -/* Store lasted switch address and channel */ -static uint16_t fpga_i2c_lasted_access_port[I2C_MASTER_CH_TOTAL]; - -enum PORT_TYPE { - NONE, - QSFP, - SFP -}; - -struct i2c_switch { - unsigned char master_bus; // I2C bus number - unsigned char switch_addr; // PCA9548 device address, 0xFF if directly connect to a bus. - unsigned char channel; // PCA9548 channel number. If the switch_addr is 0xFF, this value is ignored. - enum PORT_TYPE port_type; // QSFP/SFP tranceiver port type. - char calling_name[20]; // Calling name. -}; - -struct i2c_dev_data { - int portid; - struct i2c_switch pca9548; -}; - -/* PREDEFINED I2C SWITCH DEVICE TOPOLOGY */ -static struct i2c_switch fpga_i2c_bus_dev[] = { - /* BUS3 QSFP Exported as virtual bus */ - {I2C_MASTER_CH_3, 0x71, 2, QSFP, "QSFP1"}, {I2C_MASTER_CH_3, 0x71, 3, QSFP, "QSFP2"}, - {I2C_MASTER_CH_3, 0x71, 0, QSFP, "QSFP3"}, {I2C_MASTER_CH_3, 0x71, 1, QSFP, "QSFP4"}, - {I2C_MASTER_CH_3, 0x71, 6, QSFP, "QSFP5"}, {I2C_MASTER_CH_3, 0x71, 5, QSFP, "QSFP6"}, - {I2C_MASTER_CH_3, 0x73, 7, QSFP, "QSFP7"}, {I2C_MASTER_CH_3, 0x71, 4, QSFP, "QSFP8"}, - - {I2C_MASTER_CH_3, 0x73, 4, QSFP, "QSFP9"}, {I2C_MASTER_CH_3, 0x73, 3, QSFP, "QSFP10"}, - {I2C_MASTER_CH_3, 0x73, 6, QSFP, "QSFP11"}, {I2C_MASTER_CH_3, 0x73, 2, QSFP, "QSFP12"}, - {I2C_MASTER_CH_3, 0x73, 1, QSFP, "QSFP13"}, {I2C_MASTER_CH_3, 0x73, 5, QSFP, "QSFP14"}, - {I2C_MASTER_CH_3, 0x71, 7, QSFP, "QSFP15"}, {I2C_MASTER_CH_3, 0x73, 0, QSFP, "QSFP16"}, - - {I2C_MASTER_CH_3, 0x72, 1, QSFP, "QSFP17"}, {I2C_MASTER_CH_3, 0x72, 7, QSFP, "QSFP18"}, - {I2C_MASTER_CH_3, 0x72, 4, QSFP, "QSFP19"}, {I2C_MASTER_CH_3, 0x72, 0, QSFP, "QSFP20"}, - {I2C_MASTER_CH_3, 0x72, 5, QSFP, "QSFP21"}, {I2C_MASTER_CH_3, 0x72, 2, QSFP, "QSFP22"}, - {I2C_MASTER_CH_3, 0x70, 5, QSFP, "QSFP23"}, {I2C_MASTER_CH_3, 0x72, 6, QSFP, "QSFP24"}, - - {I2C_MASTER_CH_3, 0x72, 3, QSFP, "QSFP25"}, {I2C_MASTER_CH_3, 0x70, 6, QSFP, "QSFP26"}, - {I2C_MASTER_CH_3, 0x70, 0, QSFP, "QSFP27"}, {I2C_MASTER_CH_3, 0x70, 7, QSFP, "QSFP28"}, - {I2C_MASTER_CH_3, 0x70, 2, QSFP, "QSFP29"}, {I2C_MASTER_CH_3, 0x70, 4, QSFP, "QSFP30"}, - {I2C_MASTER_CH_3, 0x70, 3, QSFP, "QSFP31"}, {I2C_MASTER_CH_3, 0x70, 1, QSFP, "QSFP32"}, - /* BUS1 SFP+ Exported as virtual bus */ - {I2C_MASTER_CH_1, 0xFF, 0, SFP, "SFP1"}, - /* BUS2 SFP+ Exported as virtual bus */ - {I2C_MASTER_CH_2, 0xFF, 0, SFP, "SFP2"}, - /* BUS4 CPLD Access via I2C */ - {I2C_MASTER_CH_4, 0xFF, 0, NONE, "CPLD_S"}, - /* BUS5 CPLD_B */ - {I2C_MASTER_CH_5, 0xFF, 0, NONE, "CPLD_B"}, -}; - -#define VIRTUAL_I2C_PORT_LENGTH ARRAY_SIZE(fpga_i2c_bus_dev) -#define SW_I2C_CPLD_INDEX SFF_PORT_TOTAL - -struct fpga_device { - /* data mmio region */ - void __iomem *data_base_addr; - resource_size_t data_mmio_start; - resource_size_t data_mmio_len; -}; - -static struct fpga_device fpga_dev = { - .data_base_addr = 0, - .data_mmio_start = 0, - .data_mmio_len = 0, -}; - -struct silverstone_fpga_data { - struct device *sff_devices[SFF_PORT_TOTAL]; - struct i2c_client *sff_i2c_clients[SFF_PORT_TOTAL]; - struct i2c_adapter *i2c_adapter[VIRTUAL_I2C_PORT_LENGTH]; - struct mutex fpga_lock; // For FPGA internal lock - void __iomem * fpga_read_addr; - uint8_t cpld1_read_addr; - uint8_t cpld2_read_addr; -}; - -struct sff_device_data { - int portid; - enum PORT_TYPE port_type; -}; - -struct silverstone_fpga_data *fpga_data; - -/* - * Kernel object for other module drivers. - * Other module can use these kobject as a parent. - */ - -static struct kobject *fpga = NULL; -static struct kobject *cpld1 = NULL; -static struct kobject *cpld2 = NULL; - -/** - * Device node in sysfs tree. - */ -static struct device *sff_dev = NULL; - - -static ssize_t version_show(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - u32 version; - - mutex_lock(&fpga_data->fpga_lock); - version = ioread32(fpga_dev.data_base_addr + FPGA_VERSION); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d.%d\n", version >> 16, version & 0xFFFF); -} - -/** - * Show the value of the register set by 'set_fpga_reg_address' - * If the address is not set by 'set_fpga_reg_address' first, - * The version register is selected by default. - * @param buf register value in hextring - * @return number of bytes read, or an error code - */ -static ssize_t get_fpga_reg_value(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - // read data from the address - uint32_t data; - data = ioread32(fpga_data->fpga_read_addr); - return sprintf(buf, "0x%8.8x\n", data); -} -/** - * Store the register address - * @param buf address wanted to be read value of - * @return number of bytes stored, or an error code - */ -static ssize_t set_fpga_reg_address(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - uint32_t addr; - char *last; - - addr = (uint32_t)strtoul(buf, &last, 16); - if (addr == 0 && buf == last) { - return -EINVAL; - } - fpga_data->fpga_read_addr = fpga_dev.data_base_addr + addr; - return count; -} -/** - * Show value of fpga scratch register - * @param buf register value in hexstring - * @return number of bytes read, or an error code - */ -static ssize_t get_fpga_scratch(struct device *dev, struct device_attribute *devattr, - char *buf) -{ - return sprintf(buf, "0x%8.8x\n", ioread32(fpga_dev.data_base_addr + FPGA_SCRATCH) & 0xffffffff); -} -/** - * Store value of fpga scratch register - * @param buf scratch register value passing from user space - * @return number of bytes stored, or an error code - */ -static ssize_t set_fpga_scratch(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - uint32_t data; - char *last; - data = (uint32_t)strtoul(buf, &last, 16); - if (data == 0 && buf == last) { - return -EINVAL; - } - iowrite32(data, fpga_dev.data_base_addr + FPGA_SCRATCH); - return count; -} -/** - * Store a value in a specific register address - * @param buf the value and address in format '0xhhhh 0xhhhhhhhh' - * @return number of bytes sent by user space, or an error code - */ -static ssize_t set_fpga_reg_value(struct device *dev, struct device_attribute *devattr, - const char *buf, size_t count) -{ - // register are 4 bytes - uint32_t addr; - uint32_t value; - uint32_t mode = 8; - char *tok; - char clone[count]; - char *pclone = clone; - char *last; - - strcpy(clone, buf); - - mutex_lock(&fpga_data->fpga_lock); - tok = strsep((char**)&pclone, " "); - if (tok == NULL) { - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; - } - addr = (uint32_t)strtoul(tok, &last, 16); - if (addr == 0 && tok == last) { - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; - } - tok = strsep((char**)&pclone, " "); - if (tok == NULL) { - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; - } - value = (uint32_t)strtoul(tok, &last, 16); - if (value == 0 && tok == last) { - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; - } - tok = strsep((char**)&pclone, " "); - if (tok == NULL) { - mode = 32; - } else { - mode = (uint32_t)strtoul(tok, &last, 10); - if (mode == 0 && tok == last) { - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; - } - } - if (mode == 32) { - iowrite32(value, fpga_dev.data_base_addr + addr); - } else if (mode == 8) { - iowrite8(value, fpga_dev.data_base_addr + addr); - } else { - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; - } - mutex_unlock(&fpga_data->fpga_lock); - return count; -} - -/** - * Show FPGA port XCVR ready status - * @param buf 1 if the functin is ready, 0 if not. - * @return number of bytes read, or an error code - */ -static ssize_t ready_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - unsigned int REGISTER = FPGA_PORT_XCVR_READY; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> 0) & 1U); -} - -/* FPGA attributes */ -static DEVICE_ATTR( getreg, 0600, get_fpga_reg_value, set_fpga_reg_address); -static DEVICE_ATTR( scratch, 0600, get_fpga_scratch, set_fpga_scratch); -static DEVICE_ATTR( setreg, 0200, NULL , set_fpga_reg_value); -static DEVICE_ATTR_RO(ready); -static DEVICE_ATTR_RO(version); - -static struct attribute *fpga_attrs[] = { - &dev_attr_getreg.attr, - &dev_attr_scratch.attr, - &dev_attr_setreg.attr, - &dev_attr_ready.attr, - &dev_attr_version.attr, - NULL, -}; - -static struct attribute_group fpga_attr_grp = { - .attrs = fpga_attrs, -}; - -static ssize_t cpld1_version_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - u8 version; - int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], - CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x00, - I2C_SMBUS_BYTE_DATA, - (union i2c_smbus_data *)&version); - if (err < 0) - return err; - return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); -} -struct device_attribute dev_attr_cpld1_version = __ATTR(version, 0444, cpld1_version_show , NULL); - -/* SW CPLDs attributes */ -static ssize_t cpld1_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - // CPLD register is one byte - uint8_t data; - fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld1_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); - return sprintf(buf, "0x%2.2x\n", data); -} -static ssize_t cpld1_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - uint8_t addr; - char *last; - addr = (uint8_t)strtoul(buf, &last, 16); - if (addr == 0 && buf == last) { - return -EINVAL; - } - fpga_data->cpld1_read_addr = addr; - return size; -} -struct device_attribute dev_attr_cpld1_getreg = __ATTR(getreg, 0600, cpld1_getreg_show, cpld1_getreg_store); - -static ssize_t cpld1_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - // CPLD register is one byte - __u8 data; - int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); - if (err < 0) - return err; - return sprintf(buf, "0x%2.2x\n", data); -} -static ssize_t cpld1_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - // CPLD register is one byte - __u8 data; - char *last; - int err; - data = (uint8_t)strtoul(buf, &last, 16); - if (data == 0 && buf == last) { - return -EINVAL; - } - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); - if (err < 0) - return err; - return size; -} -struct device_attribute dev_attr_cpld1_scratch = __ATTR(scratch, 0600, cpld1_scratch_show, cpld1_scratch_store); - -static ssize_t cpld1_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - - uint8_t addr, value; - char *tok; - char clone[size]; - char *pclone = clone; - int err; - char *last; - - strcpy(clone, buf); - - tok = strsep((char**)&pclone, " "); - if (tok == NULL) { - return -EINVAL; - } - addr = (uint8_t)strtoul(tok, &last, 16); - if (addr == 0 && tok == last) { - return -EINVAL; - } - tok = strsep((char**)&pclone, " "); - if (tok == NULL) { - return -EINVAL; - } - value = (uint8_t)strtoul(tok, &last, 16); - if (value == 0 && tok == last) { - return -EINVAL; - } - - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); - if (err < 0) - return err; - - return size; -} -struct device_attribute dev_attr_cpld1_setreg = __ATTR(setreg, 0200, NULL, cpld1_setreg_store); - -static struct attribute *cpld1_attrs[] = { - &dev_attr_cpld1_version.attr, - &dev_attr_cpld1_getreg.attr, - &dev_attr_cpld1_scratch.attr, - &dev_attr_cpld1_setreg.attr, - NULL, -}; - -static struct attribute_group cpld1_attr_grp = { - .attrs = cpld1_attrs, -}; - -static ssize_t cpld2_version_show(struct device *dev, - struct device_attribute *attr, char *buf) -{ - u8 version; - int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], - CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x00, - I2C_SMBUS_BYTE_DATA, - (union i2c_smbus_data *)&version); - if (err < 0) - return err; - return sprintf(buf, "%d.%d\n", version >> 4, version & 0x0F); -} -struct device_attribute dev_attr_cpld2_version = __ATTR(version, 0444, cpld2_version_show , NULL); - -static ssize_t cpld2_getreg_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - // CPLD register is one byte - uint8_t data; - fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, fpga_data->cpld2_read_addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); - return sprintf(buf, "0x%2.2x\n", data); -} - -static ssize_t cpld2_getreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - // CPLD register is one byte - uint32_t addr; - char *last; - addr = (uint8_t)strtoul(buf, &last, 16); - if (addr == 0 && buf == last) { - return -EINVAL; - } - fpga_data->cpld2_read_addr = addr; - return size; -} -struct device_attribute dev_attr_cpld2_getreg = __ATTR(getreg, 0600, cpld2_getreg_show, cpld2_getreg_store); - -static ssize_t cpld2_scratch_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - // CPLD register is one byte - __u8 data; - int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); - if (err < 0) - return err; - return sprintf(buf, "0x%2.2x\n", data); -} - -static ssize_t cpld2_scratch_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - // CPLD register is one byte - __u8 data; - char *last; - int err; - - data = (uint8_t)strtoul(buf, &last, 16); - if (data == 0 && buf == last) { - return -EINVAL; - } - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, 0x01, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&data); - if (err < 0) - return err; - return size; -} -struct device_attribute dev_attr_cpld2_scratch = __ATTR(scratch, 0600, cpld2_scratch_show, cpld2_scratch_store); - -static ssize_t cpld2_setreg_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - uint8_t addr, value; - char *tok; - char clone[size]; - char *pclone = clone; - int err; - char *last; - - strcpy(clone, buf); - - tok = strsep((char**)&pclone, " "); - if (tok == NULL) { - return -EINVAL; - } - addr = (uint8_t)strtoul(tok, &last, 16); - if (addr == 0 && tok == last) { - return -EINVAL; - } - tok = strsep((char**)&pclone, " "); - if (tok == NULL) { - return -EINVAL; - } - value = (uint8_t)strtoul(tok, &last, 16); - if (value == 0 && tok == last) { - return -EINVAL; - } - - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_WRITE, addr, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&value); - if (err < 0) - return err; - - return size; -} -struct device_attribute dev_attr_cpld2_setreg = __ATTR(setreg, 0200, NULL, cpld2_setreg_store); - -static struct attribute *cpld2_attrs[] = { - &dev_attr_cpld2_version.attr, - &dev_attr_cpld2_getreg.attr, - &dev_attr_cpld2_scratch.attr, - &dev_attr_cpld2_setreg.attr, - NULL, -}; - -static struct attribute_group cpld2_attr_grp = { - .attrs = cpld2_attrs, -}; - -/* QSFP/SFP+ attributes */ -static ssize_t qsfp_modirq_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> STAT_IRQ) & 1U); -} -DEVICE_ATTR_RO(qsfp_modirq); - -static ssize_t qsfp_modprs_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> STAT_PRESENT) & 1U); -} -DEVICE_ATTR_RO(qsfp_modprs); - -static ssize_t sfp_txfault_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> STAT_TXFAULT) & 1U); -} -DEVICE_ATTR_RO(sfp_txfault); - -static ssize_t sfp_rxlos_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> STAT_RXLOS) & 1U); -} -DEVICE_ATTR_RO(sfp_rxlos); - -static ssize_t sfp_modabs_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_STATUS_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> STAT_MODABS) & 1U); -} -DEVICE_ATTR_RO(sfp_modabs); - -static ssize_t qsfp_lpmode_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> CTRL_LPMOD) & 1U); -} -static ssize_t qsfp_lpmode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - ssize_t status; - long value; - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - status = kstrtol(buf, 0, &value); - if (status == 0) { - // if value is 0, disable the lpmode - data = ioread32(fpga_dev.data_base_addr + REGISTER); - if (!value) - data = data & ~( (u32)0x1 << CTRL_LPMOD); - else - data = data | ((u32)0x1 << CTRL_LPMOD); - iowrite32(data, fpga_dev.data_base_addr + REGISTER); - status = size; - } - mutex_unlock(&fpga_data->fpga_lock); - return status; -} -DEVICE_ATTR_RW(qsfp_lpmode); - -static ssize_t qsfp_reset_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> CTRL_RST) & 1U); -} - -static ssize_t qsfp_reset_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - ssize_t status; - long value; - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - status = kstrtol(buf, 0, &value); - if (status == 0) { - // if value is 0, reset signal is low - data = ioread32(fpga_dev.data_base_addr + REGISTER); - if (!value) - data = data & ~( (u32)0x1 << CTRL_RST); - else - data = data | ((u32)0x1 << CTRL_RST); - iowrite32(data, fpga_dev.data_base_addr + REGISTER); - status = size; - } - mutex_unlock(&fpga_data->fpga_lock); - return status; -} -DEVICE_ATTR_RW(qsfp_reset); - -static ssize_t sfp_txdisable_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - data = ioread32(fpga_dev.data_base_addr + REGISTER); - mutex_unlock(&fpga_data->fpga_lock); - return sprintf(buf, "%d\n", (data >> CTRL_TXDIS) & 1U); -} -static ssize_t sfp_txdisable_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - ssize_t status; - long value; - u32 data; - struct sff_device_data *dev_data = dev_get_drvdata(dev); - unsigned int portid = dev_data->portid; - unsigned int REGISTER = SFF_PORT_CTRL_BASE + (portid - 1) * 0x10; - - mutex_lock(&fpga_data->fpga_lock); - status = kstrtol(buf, 0, &value); - if (status == 0) { - // check if value is 0 clear - data = ioread32(fpga_dev.data_base_addr + REGISTER); - if (!value) - data = data & ~( (u32)0x1 << CTRL_TXDIS); - else - data = data | ((u32)0x1 << CTRL_TXDIS); - iowrite32(data, fpga_dev.data_base_addr + REGISTER); - status = size; - } - mutex_unlock(&fpga_data->fpga_lock); - return status; -} -DEVICE_ATTR_RW(sfp_txdisable); - -static struct attribute *sff_attrs[] = { - &dev_attr_qsfp_modirq.attr, - &dev_attr_qsfp_modprs.attr, - &dev_attr_qsfp_lpmode.attr, - &dev_attr_qsfp_reset.attr, - &dev_attr_sfp_txfault.attr, - &dev_attr_sfp_rxlos.attr, - &dev_attr_sfp_modabs.attr, - &dev_attr_sfp_txdisable.attr, - NULL, -}; - -static struct attribute_group sff_attr_grp = { - .attrs = sff_attrs, -}; - -static const struct attribute_group *sff_attr_grps[] = { - &sff_attr_grp, - NULL -}; - - -static ssize_t port_led_mode_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - // value can be "nomal", "test" - __u8 led_mode_1, led_mode_2; - int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); - if (err < 0) - return err; - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_2); - if (err < 0) - return err; - return sprintf(buf, "%s %s\n", - led_mode_1 ? "test" : "normal", - led_mode_2 ? "test" : "normal"); -} -static ssize_t port_led_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - int status; - __u8 led_mode_1; - if (sysfs_streq(buf, "test")) { - led_mode_1 = 0x01; - } else if (sysfs_streq(buf, "normal")) { - led_mode_1 = 0x00; - } else { - return -EINVAL; - } - status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, - I2C_SMBUS_WRITE, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); - status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, - I2C_SMBUS_WRITE, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_mode_1); - return size; -} -DEVICE_ATTR_RW(port_led_mode); - -// Only work when port_led_mode set to 1 -static ssize_t port_led_color_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - // value can be R/G/B/C/M/Y/W/OFF - __u8 led_color1, led_color2; - int err; - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color1); - if (err < 0) - return err; - err = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, I2C_SMBUS_READ, 0x09, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color2); - if (err < 0) - return err; - return sprintf(buf, "%s %s\n", - led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "red" : led_color1 == 0x04 ? - "yellow" : led_color1 == 0x03 ? "blue" : led_color1 == 0x02 ? "cyan" : led_color1 == 0x01 ? "magenta" : "white", - led_color1 == 0x07 ? "off" : led_color1 == 0x06 ? "green" : led_color1 == 0x05 ? "red" : led_color1 == 0x04 ? - "yellow" : led_color1 == 0x03 ? "blue" : led_color1 == 0x02 ? "cyan" : led_color1 == 0x01 ? "magenta" : "white"); -} - -static ssize_t port_led_color_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) -{ - int status; - __u8 led_color; - if (sysfs_streq(buf, "off")) { - led_color = 0x07; - } else if (sysfs_streq(buf, "green")) { - led_color = 0x06; - } else if (sysfs_streq(buf, "red")) { - led_color = 0x05; - } else if (sysfs_streq(buf, "yellow")) { - led_color = 0x04; - } else if (sysfs_streq(buf, "blue")) { - led_color = 0x03; - } else if (sysfs_streq(buf, "cyan")) { - led_color = 0x02; - } else if (sysfs_streq(buf, "magenta")) { - led_color = 0x01; - } else if (sysfs_streq(buf, "white")) { - led_color = 0x00; - } else { - status = -EINVAL; - return status; - } - status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, - I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color); - status = fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, - I2C_SMBUS_WRITE, 0x0A, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&led_color); - return size; -} -DEVICE_ATTR_RW(port_led_color); - -static struct attribute *sff_led_test[] = { - &dev_attr_port_led_mode.attr, - &dev_attr_port_led_color.attr, - NULL, -}; - -static struct attribute_group sff_led_test_grp = { - .attrs = sff_led_test, -}; - -static struct device * silverstone_sff_init(int portid) { - struct sff_device_data *new_data; - struct device *new_device; - - new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); - if (!new_data) { - printk(KERN_ALERT "Cannot alloc sff device data @port%d", portid); - return NULL; - } - /* The QSFP port ID start from 1 */ - new_data->portid = portid + 1; - new_data->port_type = fpga_i2c_bus_dev[portid].port_type; - new_device = device_create_with_groups(fpgafwclass, sff_dev, MKDEV(0, 0), new_data, sff_attr_grps, "%s", fpga_i2c_bus_dev[portid].calling_name); - if (IS_ERR(new_device)) { - printk(KERN_ALERT "Cannot create sff device @port%d", portid); - kfree(new_data); - return NULL; - } - return new_device; -} - -static int i2c_wait_ack(struct i2c_adapter *a, unsigned long timeout, int writing) { - int error = 0; - int Status; - - struct i2c_dev_data *new_data = i2c_get_adapdata(a); - void __iomem *pci_bar = fpga_dev.data_base_addr; - - unsigned int REG_FDR0; - unsigned int REG_CR0; - unsigned int REG_SR0; - unsigned int REG_DR0; - unsigned int REG_ID0; - - unsigned int master_bus = new_data->pca9548.master_bus; - - if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { - error = -EINVAL; - return error; - } - - REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; - REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; - REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; - REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; - REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; - - check(pci_bar + REG_SR0); - check(pci_bar + REG_CR0); - - timeout = jiffies + msecs_to_jiffies(timeout); - while (1) { - Status = ioread8(pci_bar + REG_SR0); - if (jiffies > timeout) { - info("Status %2.2X", Status); - info("Error Timeout"); - error = -ETIMEDOUT; - break; - } - - - if (Status & (1 << I2C_SR_BIT_MIF)) { - break; - } - - if (writing == 0 && (Status & (1 << I2C_SR_BIT_MCF))) { - break; - } - } - Status = ioread8(pci_bar + REG_SR0); - iowrite8(0, pci_bar + REG_SR0); - - if (error < 0) { - info("Status %2.2X", Status); - return error; - } - - if (!(Status & (1 << I2C_SR_BIT_MCF))) { - info("Error Unfinish"); - return -EIO; - } - - if (Status & (1 << I2C_SR_BIT_MAL)) { - info("Error MAL"); - return -EAGAIN; - } - - if (Status & (1 << I2C_SR_BIT_RXAK)) { - info( "SL No Acknowlege"); - if (writing) { - info("Error No Acknowlege"); - iowrite8(1 << I2C_CR_BIT_MEN, pci_bar + REG_CR0); - return -ENXIO; - } - } else { - info( "SL Acknowlege"); - } - - return 0; -} - -static int smbus_access(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data) -{ - int error = 0; - int cnt = 0; - int bid = 0; - struct i2c_dev_data *dev_data; - void __iomem *pci_bar; - unsigned int portid, master_bus; - unsigned int REG_FDR0; - unsigned int REG_CR0; - unsigned int REG_SR0; - unsigned int REG_DR0; - unsigned int REG_ID0; - - /* Write the command register */ - dev_data = i2c_get_adapdata(adapter); - portid = dev_data->portid; - pci_bar = fpga_dev.data_base_addr; - master_bus = dev_data->pca9548.master_bus; - REG_FDR0 = I2C_MASTER_FREQ_1 + (master_bus - 1) * 0x0100; - REG_CR0 = I2C_MASTER_CTRL_1 + (master_bus - 1) * 0x0100; - REG_SR0 = I2C_MASTER_STATUS_1 + (master_bus - 1) * 0x0100; - REG_DR0 = I2C_MASTER_DATA_1 + (master_bus - 1) * 0x0100; - REG_ID0 = I2C_MASTER_PORT_ID_1 + (master_bus - 1) * 0x0100; - - if (master_bus < I2C_MASTER_CH_1 || master_bus > I2C_MASTER_CH_TOTAL) { - error = -EINVAL; - goto Done; - } - -#ifdef DEBUG_KERN - printk(KERN_INFO "portid %2d|@ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " - , portid, addr, flags, rw, rw == 1 ? "READ " : "WRITE" - , size, size == 0 ? "QUICK" : - size == 1 ? "BYTE" : - size == 2 ? "BYTE_DATA" : - size == 3 ? "WORD_DATA" : - size == 4 ? "PROC_CALL" : - size == 5 ? "BLOCK_DATA" : "ERROR" - , cmd); -#endif - /* Map the size to what the chip understands */ - switch (size) { - case I2C_SMBUS_QUICK: - case I2C_SMBUS_BYTE: - case I2C_SMBUS_BYTE_DATA: - case I2C_SMBUS_WORD_DATA: - case I2C_SMBUS_BLOCK_DATA: - break; - default: - printk(KERN_INFO "Unsupported transaction %d\n", size); - error = -EOPNOTSUPP; - goto Done; - } - - iowrite8(portid, pci_bar + REG_ID0); - - ////[S][ADDR/R] - //Clear status register - iowrite8(0, pci_bar + REG_SR0); - iowrite8(1 << I2C_CR_BIT_MIEN | 1 << I2C_CR_BIT_MTX | 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); - SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); - - if (rw == I2C_SMBUS_READ && - (size == I2C_SMBUS_QUICK || size == I2C_SMBUS_BYTE)) { - // sent device address with Read mode - iowrite8(addr << 1 | 0x01, pci_bar + REG_DR0); - } else { - // sent device address with Write mode - iowrite8(addr << 1 | 0x00, pci_bar + REG_DR0); - } - - - - info( "MS Start"); - - //// Wait {A} - error = i2c_wait_ack(adapter, 12, 1); - if (error < 0) { - info( "get error %d", error); - goto Done; - } - - //// [CMD]{A} - if (size == I2C_SMBUS_BYTE_DATA || - size == I2C_SMBUS_WORD_DATA || - size == I2C_SMBUS_BLOCK_DATA || - (size == I2C_SMBUS_BYTE && rw == I2C_SMBUS_WRITE)) { - - //sent command code to data register - iowrite8(cmd, pci_bar + REG_DR0); - info( "MS Send CMD 0x%2.2X", cmd); - - // Wait {A} - error = i2c_wait_ack(adapter, 12, 1); - if (error < 0) { - info( "get error %d", error); - goto Done; - } - } - - switch (size) { - case I2C_SMBUS_BYTE_DATA: - cnt = 1; break; - case I2C_SMBUS_WORD_DATA: - cnt = 2; break; - case I2C_SMBUS_BLOCK_DATA: - // in block data mode keep number of byte in block[0] - cnt = data->block[0]; - break; - default: - cnt = 0; break; - } - - // [CNT] used only bloack data write - if (size == I2C_SMBUS_BLOCK_DATA && rw == I2C_SMBUS_WRITE) { - - iowrite8(cnt, pci_bar + REG_DR0); - info( "MS Send CNT 0x%2.2X", cnt); - - // Wait {A} - error = i2c_wait_ack(adapter, 12, 1); - if (error < 0) { - info( "get error %d", error); - goto Done; - } - } - - // [DATA]{A} - if ( rw == I2C_SMBUS_WRITE && ( - size == I2C_SMBUS_BYTE || - size == I2C_SMBUS_BYTE_DATA || - size == I2C_SMBUS_WORD_DATA || - size == I2C_SMBUS_BLOCK_DATA - )) { - int bid = 0; - info( "MS prepare to sent [%d bytes]", cnt); - if (size == I2C_SMBUS_BLOCK_DATA ) { - bid = 1; // block[0] is cnt; - cnt += 1; // offset from block[0] - } - for (; bid < cnt; bid++) { - - iowrite8(data->block[bid], pci_bar + REG_DR0); - info( " Data > %2.2X", data->block[bid]); - // Wait {A} - error = i2c_wait_ack(adapter, 12, 1); - if (error < 0) { - goto Done; - } - } - } - - //REPEATE START - if ( rw == I2C_SMBUS_READ && ( - size == I2C_SMBUS_BYTE_DATA || - size == I2C_SMBUS_WORD_DATA || - size == I2C_SMBUS_BLOCK_DATA - )) { - info( "MS Repeated Start"); - - SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MEN); - iowrite8(1 << I2C_CR_BIT_MIEN | - 1 << I2C_CR_BIT_MTX | - 1 << I2C_CR_BIT_MSTA | - 1 << I2C_CR_BIT_RSTA , pci_bar + REG_CR0); - SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_MEN); - - // sent Address with Read mode - iowrite8( addr << 1 | 0x1 , pci_bar + REG_DR0); - - // Wait {A} - error = i2c_wait_ack(adapter, 12, 1); - if (error < 0) { - goto Done; - } - - } - - if ( rw == I2C_SMBUS_READ && ( - size == I2C_SMBUS_BYTE || - size == I2C_SMBUS_BYTE_DATA || - size == I2C_SMBUS_WORD_DATA || - size == I2C_SMBUS_BLOCK_DATA - )) { - - switch (size) { - case I2C_SMBUS_BYTE: - case I2C_SMBUS_BYTE_DATA: - cnt = 1; break; - case I2C_SMBUS_WORD_DATA: - cnt = 2; break; - case I2C_SMBUS_BLOCK_DATA: - //will be changed after recived first data - cnt = 3; break; - default: - cnt = 0; break; - } - - info( "MS Receive"); - - //set to Receive mode - iowrite8(1 << I2C_CR_BIT_MEN | - 1 << I2C_CR_BIT_MIEN | - 1 << I2C_CR_BIT_MSTA , pci_bar + REG_CR0); - - for (bid = -1; bid < cnt; bid++) { - - // Wait {A} - error = i2c_wait_ack(adapter, 12, 0); - if (error < 0) { - goto Done; - } - - if (bid == cnt - 2) { - info( "SET NAK"); - SET_REG_BIT_H(pci_bar + REG_CR0, I2C_CR_BIT_TXAK); - } - - if (bid < 0) { - ioread8(pci_bar + REG_DR0); - info( "READ Dummy Byte" ); - } else { - - if (bid == cnt - 1) { - info ( "SET STOP in read loop"); - SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); - } - data->block[bid] = ioread8(pci_bar + REG_DR0); - - info( "DATA IN [%d] %2.2X", bid, data->block[bid]); - - if (size == I2C_SMBUS_BLOCK_DATA && bid == 0) { - cnt = data->block[0] + 1; - } - } - } - } - - //[P] - SET_REG_BIT_L(pci_bar + REG_CR0, I2C_CR_BIT_MSTA); - i2c_wait_ack(adapter, 12, 0); - info( "MS STOP"); - -Done: - iowrite8(1 << I2C_CR_BIT_MEN, pci_bar + REG_CR0); - check(pci_bar + REG_CR0); - check(pci_bar + REG_SR0); -#ifdef DEBUG_KERN - printk(KERN_INFO "END --- Error code %d", error); -#endif - - return error; -} - -/** - * Wrapper of smbus_access access with PCA9548 I2C switch management. - * This function set PCA9548 switches to the proper slave channel. - * Only one channel among switches chip is selected during communication time. - * - * Note: If the bus does not have any PCA9548 on it, the switch_addr must be - * set to 0xFF, it will use normal smbus_access function. - */ -static int fpga_i2c_access(struct i2c_adapter *adapter, u16 addr, - unsigned short flags, char rw, u8 cmd, - int size, union i2c_smbus_data *data) -{ - int error = 0; - struct i2c_dev_data *dev_data; - unsigned char master_bus; - unsigned char switch_addr; - unsigned char channel; - uint16_t prev_port = 0; - unsigned char prev_switch; - unsigned char prev_ch; - int retry; - - dev_data = i2c_get_adapdata(adapter); - master_bus = dev_data->pca9548.master_bus; - switch_addr = dev_data->pca9548.switch_addr; - channel = dev_data->pca9548.channel; - - // Acquire the master resource. - mutex_lock(&fpga_i2c_master_locks[master_bus - 1]); - prev_port = fpga_i2c_lasted_access_port[master_bus - 1]; - prev_switch = (unsigned char)(prev_port >> 8) & 0xFF; - prev_ch = (unsigned char)(prev_port & 0xFF); - - if (switch_addr != 0xFF) { - - // Check lasted access switch address on a master - if ( prev_switch != switch_addr && prev_switch != 0 ) { - // reset prev_port PCA9548 chip - retry = 3; - while(retry--){ - error = smbus_access(adapter, (u16)(prev_switch), flags, I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); - if(error >= 0){ - break; - }else{ - dev_dbg(&adapter->dev,"Failed to deselect ch %d of 0x%x, CODE %d\n", prev_ch, prev_switch, error); - } - } - if(retry == 0) - goto release_unlock; - // set PCA9548 to current channel - retry = 3; - while(retry--){ - error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); - if(error >= 0){ - break; - }else{ - dev_dbg(&adapter->dev,"Failed to select ch %d of 0x%x, CODE %d\n", channel, switch_addr, error); - } - } - if(retry == 0) - goto release_unlock; - // update lasted port - fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; - - } else { - // check if channel is also changes - if ( prev_ch != channel || prev_switch == 0 ) { - // set new PCA9548 at switch_addr to current - retry = 3; - while(retry--){ - error = smbus_access(adapter, switch_addr, flags, I2C_SMBUS_WRITE, 1 << channel, I2C_SMBUS_BYTE, NULL); - if(error >= 0){ - break; - }else{ - dev_dbg(&adapter->dev,"Failed to select ch %d of 0x%x, CODE %d\n", channel, switch_addr, error); - } - } - if(retry == 0) - goto release_unlock; - // update lasted port - fpga_i2c_lasted_access_port[master_bus - 1] = switch_addr << 8 | channel; - } - } - } - - // Do SMBus communication - error = smbus_access(adapter, addr, flags, rw, cmd, size, data); - if(error < 0){ - dev_dbg( &adapter->dev,"smbus_xfer failed (%d) @ 0x%2.2X|f 0x%4.4X|(%d)%-5s| (%d)%-10s|CMD %2.2X " - , error, addr, flags, rw, rw == 1 ? "READ " : "WRITE" - , size, size == 0 ? "QUICK" : - size == 1 ? "BYTE" : - size == 2 ? "BYTE_DATA" : - size == 3 ? "WORD_DATA" : - size == 4 ? "PROC_CALL" : - size == 5 ? "BLOCK_DATA" : - size == 8 ? "I2C_BLOCK_DATA" : "ERROR" - , cmd); - } - -release_unlock: - mutex_unlock(&fpga_i2c_master_locks[master_bus - 1]); - dev_dbg(&adapter->dev,"switch ch %d of 0x%x -> ch %d of 0x%x\n", prev_ch, prev_switch, channel, switch_addr); - return error; -} - - - -/** - * A callback function show available smbus functions. - */ -static u32 fpga_i2c_func(struct i2c_adapter *a) -{ - return I2C_FUNC_SMBUS_QUICK | - I2C_FUNC_SMBUS_BYTE | - I2C_FUNC_SMBUS_BYTE_DATA | - I2C_FUNC_SMBUS_WORD_DATA | - I2C_FUNC_SMBUS_BLOCK_DATA; -} - -static const struct i2c_algorithm silverstone_i2c_algorithm = { - .smbus_xfer = fpga_i2c_access, - .functionality = fpga_i2c_func, -}; - -/** - * Create virtual I2C bus adapter for switch devices - * @param pdev platform device pointer - * @param portid virtual i2c port id for switch device mapping - * @param bus_number_offset bus offset for virtual i2c adapter in system - * @return i2c adapter. - * - * When bus_number_offset is -1, created adapter with dynamic bus number. - * Otherwise create adapter at i2c bus = bus_number_offset + portid. - */ -static struct i2c_adapter * silverstone_i2c_init(struct platform_device *pdev, int portid, int bus_number_offset) -{ - int error; - - struct i2c_adapter *new_adapter; - struct i2c_dev_data *new_data; - void __iomem *i2c_freq_base_reg; - - new_adapter = kzalloc(sizeof(*new_adapter), GFP_KERNEL); - if (!new_adapter) { - printk(KERN_ALERT "Cannot alloc i2c adapter for %s", fpga_i2c_bus_dev[portid].calling_name); - return NULL; - } - - new_adapter->owner = THIS_MODULE; - new_adapter->class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - new_adapter->algo = &silverstone_i2c_algorithm; - /* If the bus offset is -1, use dynamic bus number */ - if (bus_number_offset == -1) { - new_adapter->nr = -1; - } else { - new_adapter->nr = bus_number_offset + portid; - } - - new_data = kzalloc(sizeof(*new_data), GFP_KERNEL); - if (!new_data) { - printk(KERN_ALERT "Cannot alloc i2c data for %s", fpga_i2c_bus_dev[portid].calling_name); - kfree_sensitive(new_adapter); - return NULL; - } - - new_data->portid = portid; - new_data->pca9548.master_bus = fpga_i2c_bus_dev[portid].master_bus; - new_data->pca9548.switch_addr = fpga_i2c_bus_dev[portid].switch_addr; - new_data->pca9548.channel = fpga_i2c_bus_dev[portid].channel; - strcpy(new_data->pca9548.calling_name, fpga_i2c_bus_dev[portid].calling_name); - - snprintf(new_adapter->name, sizeof(new_adapter->name), - "SMBus I2C Adapter PortID: %s", new_data->pca9548.calling_name); - - i2c_freq_base_reg = fpga_dev.data_base_addr + I2C_MASTER_FREQ_1; - iowrite8(0x07, i2c_freq_base_reg + (new_data->pca9548.master_bus - 1) * 0x100); // 0x07 400kHz - i2c_set_adapdata(new_adapter, new_data); - error = i2c_add_numbered_adapter(new_adapter); - if (error < 0) { - printk(KERN_ALERT "Cannot add i2c adapter %s", new_data->pca9548.calling_name); - kfree_sensitive(new_adapter); - kfree_sensitive(new_data); - return NULL; - } - - return new_adapter; -}; - -static void silverstone_dev_release( struct device * dev) -{ - return; -} - -static struct platform_device silverstone_dev = { - .name = DRIVER_NAME, - .id = -1, - .num_resources = 0, - .resource = NULL, - .dev = { - .release = silverstone_dev_release, - } -}; - -/** - * Board info for QSFP/SFP+ eeprom. - * Note: Using OOM optoe as I2C eeprom driver. - * https://www.opencompute.org/wiki/Networking/SpecsAndDesigns#Open_Optical_Monitoring - */ -static struct i2c_board_info sff8436_eeprom_info[] = { - { I2C_BOARD_INFO("optoe1", 0x50) }, //For QSFP w/ sff8436 - { I2C_BOARD_INFO("optoe2", 0x50) }, //For SFP+ w/ sff8472 -}; - -static int silverstone_drv_probe(struct platform_device *pdev) -{ - int ret = 0; - int portid_count; - uint8_t cpld1_version, cpld2_version; - uint16_t prev_i2c_switch = 0; - struct sff_device_data *sff_data; - - /* The device class need to be instantiated before this function called */ - BUG_ON(fpgafwclass == NULL); - - fpga_data = devm_kzalloc(&pdev->dev, sizeof(struct silverstone_fpga_data), - GFP_KERNEL); - - if (!fpga_data) - return -ENOMEM; - - // Set default read address to VERSION - fpga_data->fpga_read_addr = fpga_dev.data_base_addr + FPGA_VERSION; - fpga_data->cpld1_read_addr = 0x00; - fpga_data->cpld2_read_addr = 0x00; - - mutex_init(&fpga_data->fpga_lock); - for (ret = I2C_MASTER_CH_1 ; ret <= I2C_MASTER_CH_TOTAL; ret++) { - mutex_init(&fpga_i2c_master_locks[ret - 1]); - } - - fpga = kobject_create_and_add("FPGA", &pdev->dev.kobj); - if (!fpga) { - kfree_sensitive(fpga_data); - return -ENOMEM; - } - - ret = sysfs_create_group(fpga, &fpga_attr_grp); - if (ret != 0) { - printk(KERN_ERR "Cannot create FPGA sysfs attributes\n"); - kobject_put(fpga); - kfree_sensitive(fpga_data); - return ret; - } - - cpld1 = kobject_create_and_add("CPLD1", &pdev->dev.kobj); - if (!cpld1) { - sysfs_remove_group(fpga, &fpga_attr_grp); - kobject_put(fpga); - kfree_sensitive(fpga_data); - return -ENOMEM; - } - ret = sysfs_create_group(cpld1, &cpld1_attr_grp); - if (ret != 0) { - printk(KERN_ERR "Cannot create CPLD1 sysfs attributes\n"); - kobject_put(cpld1); - sysfs_remove_group(fpga, &fpga_attr_grp); - kobject_put(fpga); - kfree_sensitive(fpga_data); - return ret; - } - - cpld2 = kobject_create_and_add("CPLD2", &pdev->dev.kobj); - if (!cpld2) { - sysfs_remove_group(cpld1, &cpld1_attr_grp); - kobject_put(cpld1); - sysfs_remove_group(fpga, &fpga_attr_grp); - kobject_put(fpga); - kfree_sensitive(fpga_data); - return -ENOMEM; - } - ret = sysfs_create_group(cpld2, &cpld2_attr_grp); - if (ret != 0) { - printk(KERN_ERR "Cannot create CPLD2 sysfs attributes\n"); - kobject_put(cpld2); - sysfs_remove_group(cpld1, &cpld1_attr_grp); - kobject_put(cpld1); - sysfs_remove_group(fpga, &fpga_attr_grp); - kobject_put(fpga); - kfree_sensitive(fpga_data); - return ret; - } - - sff_dev = device_create(fpgafwclass, NULL, MKDEV(0, 0), NULL, "sff_device"); - if (IS_ERR(sff_dev)) { - printk(KERN_ERR "Failed to create sff device\n"); - sysfs_remove_group(cpld2, &cpld2_attr_grp); - kobject_put(cpld2); - sysfs_remove_group(cpld1, &cpld1_attr_grp); - kobject_put(cpld1); - sysfs_remove_group(fpga, &fpga_attr_grp); - kobject_put(fpga); - kfree_sensitive(fpga_data); - return PTR_ERR(sff_dev); - } - - ret = sysfs_create_group(&sff_dev->kobj, &sff_led_test_grp); - if (ret != 0) { - printk(KERN_ERR "Cannot create SFF attributes\n"); - device_destroy(fpgafwclass, MKDEV(0, 0)); - sysfs_remove_group(cpld2, &cpld2_attr_grp); - kobject_put(cpld2); - sysfs_remove_group(cpld1, &cpld1_attr_grp); - kobject_put(cpld1); - sysfs_remove_group(fpga, &fpga_attr_grp); - kobject_put(fpga); - kfree_sensitive(fpga_data); - return ret; - } - - ret = sysfs_create_link(&pdev->dev.kobj, &sff_dev->kobj, "SFF"); - if (ret != 0) { - sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); - device_destroy(fpgafwclass, MKDEV(0, 0)); - sysfs_remove_group(cpld2, &cpld2_attr_grp); - kobject_put(cpld2); - sysfs_remove_group(cpld1, &cpld1_attr_grp); - kobject_put(cpld1); - sysfs_remove_group(fpga, &fpga_attr_grp); - kobject_put(fpga); - kfree_sensitive(fpga_data); - return ret; - } - - for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { - fpga_data->i2c_adapter[portid_count] = silverstone_i2c_init(pdev, portid_count, VIRTUAL_I2C_BUS_OFFSET); - } - - /* Init SFF devices */ - for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { - struct i2c_adapter *i2c_adap = fpga_data->i2c_adapter[portid_count]; - if (i2c_adap) { - fpga_data->sff_devices[portid_count] = silverstone_sff_init(portid_count); - sff_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); - BUG_ON(sff_data == NULL); - if ( sff_data->port_type == QSFP ) { - fpga_data->sff_i2c_clients[portid_count] = i2c_new_client_device(i2c_adap, &sff8436_eeprom_info[0]); - } else { - fpga_data->sff_i2c_clients[portid_count] = i2c_new_client_device(i2c_adap, &sff8436_eeprom_info[1]); - } - sff_data = NULL; - sysfs_create_link(&fpga_data->sff_devices[portid_count]->kobj, - &fpga_data->sff_i2c_clients[portid_count]->dev.kobj, - "i2c"); - } - } - -#ifdef TEST_MODE - return 0; -#endif - fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD1_SLAVE_ADDR, 0x00, - I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld1_version); - fpga_i2c_access(fpga_data->i2c_adapter[SW_I2C_CPLD_INDEX], CPLD2_SLAVE_ADDR, 0x00, - I2C_SMBUS_READ, 0x00, I2C_SMBUS_BYTE_DATA, (union i2c_smbus_data*)&cpld2_version); - - printk(KERN_INFO "Switch CPLD1 VERSION: %2.2x\n", cpld1_version); - printk(KERN_INFO "Switch CPLD2 VERSION: %2.2x\n", cpld2_version); - - - /* Init I2C buses that has PCA9548 switch device. */ - for (portid_count = 0; portid_count < VIRTUAL_I2C_PORT_LENGTH; portid_count++) { - - struct i2c_dev_data *dev_data; - unsigned char master_bus; - unsigned char switch_addr; - - dev_data = i2c_get_adapdata(fpga_data->i2c_adapter[portid_count]); - master_bus = dev_data->pca9548.master_bus; - switch_addr = dev_data->pca9548.switch_addr; - - if (switch_addr != 0xFF) { - - if (prev_i2c_switch != ( (master_bus << 8) | switch_addr) ) { - // Found the bus with PCA9548, trying to clear all switch in it. - smbus_access(fpga_data->i2c_adapter[portid_count], switch_addr, 0x00, I2C_SMBUS_WRITE, 0x00, I2C_SMBUS_BYTE, NULL); - prev_i2c_switch = ( master_bus << 8 ) | switch_addr; - } - } - } - return 0; -} - -static int silverstone_drv_remove(struct platform_device *pdev) -{ - int portid_count; - struct sff_device_data *rem_data; - - for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { - sysfs_remove_link(&fpga_data->sff_devices[portid_count]->kobj, "i2c"); - i2c_unregister_device(fpga_data->sff_i2c_clients[portid_count]); - } - - for (portid_count = 0 ; portid_count < VIRTUAL_I2C_PORT_LENGTH ; portid_count++) { - if (fpga_data->i2c_adapter[portid_count] != NULL) { - info(KERN_INFO "<%x>", fpga_data->i2c_adapter[portid_count]); - i2c_del_adapter(fpga_data->i2c_adapter[portid_count]); - } - } - - for (portid_count = 0; portid_count < SFF_PORT_TOTAL; portid_count++) { - if (fpga_data->sff_devices[portid_count] != NULL) { - rem_data = dev_get_drvdata(fpga_data->sff_devices[portid_count]); - device_unregister(fpga_data->sff_devices[portid_count]); - put_device(fpga_data->sff_devices[portid_count]); - kfree(rem_data); - } - } - - sysfs_remove_group(fpga, &fpga_attr_grp); - sysfs_remove_group(cpld1, &cpld1_attr_grp); - sysfs_remove_group(cpld2, &cpld2_attr_grp); - sysfs_remove_group(&sff_dev->kobj, &sff_led_test_grp); - kobject_put(fpga); - kobject_put(cpld1); - kobject_put(cpld2); - device_destroy(fpgafwclass, MKDEV(0, 0)); - devm_kfree(&pdev->dev, fpga_data); - return 0; -} - -#ifdef TEST_MODE -#define FPGA_PCI_BAR_NUM 2 -#else -#define FPGA_PCI_BAR_NUM 0 -#endif - -static struct platform_driver silverstone_drv = { - .probe = silverstone_drv_probe, - .remove = __exit_p(silverstone_drv_remove), - .driver = { - .name = DRIVER_NAME, - }, -}; - -static const struct pci_device_id fpga_id_table[] = { - { PCI_VDEVICE(XILINX, FPGA_PCIE_DEVICE_ID) }, - { PCI_VDEVICE(TEST, TEST_PCIE_DEVICE_ID) }, - {0, } -}; - -MODULE_DEVICE_TABLE(pci, fpga_id_table); - -static int fpga_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) -{ - int err; - struct device *dev = &pdev->dev; - uint32_t fpga_version; - - if ((err = pci_enable_device(pdev))) { - dev_err(dev, "pci_enable_device probe error %d for device %s\n", - err, pci_name(pdev)); - return err; - } - - if ((err = pci_request_regions(pdev, FPGA_PCI_NAME)) < 0) { - dev_err(dev, "pci_request_regions error %d\n", err); - goto pci_disable; - } - - /* bar0: data mmio region */ - fpga_dev.data_mmio_start = pci_resource_start(pdev, FPGA_PCI_BAR_NUM); - fpga_dev.data_mmio_len = pci_resource_len(pdev, FPGA_PCI_BAR_NUM); - fpga_dev.data_base_addr = pci_iomap(pdev, FPGA_PCI_BAR_NUM, 0); - if (!fpga_dev.data_base_addr) { - dev_err(dev, "cannot iomap region of size %lu\n", - (unsigned long)fpga_dev.data_mmio_len); - goto pci_release; - } - dev_info(dev, "data_mmio iomap base = 0x%lx \n", - (unsigned long)fpga_dev.data_base_addr); - dev_info(dev, "data_mmio_start = 0x%lx data_mmio_len = %lu\n", - (unsigned long)fpga_dev.data_mmio_start, - (unsigned long)fpga_dev.data_mmio_len); - - printk(KERN_INFO "FPGA PCIe driver probe OK.\n"); - printk(KERN_INFO "FPGA ioremap registers of size %lu\n", (unsigned long)fpga_dev.data_mmio_len); - printk(KERN_INFO "FPGA Virtual BAR %d at %8.8lx - %8.8lx\n", FPGA_PCI_BAR_NUM, - (unsigned long)fpga_dev.data_base_addr, - (unsigned long)(fpga_dev.data_base_addr + fpga_dev.data_mmio_len)); - printk(KERN_INFO ""); - fpga_version = ioread32(fpga_dev.data_base_addr); - printk(KERN_INFO "FPGA VERSION : %8.8x\n", fpga_version); - fpgafw_init(); - platform_device_register(&silverstone_dev); - platform_driver_register(&silverstone_drv); - return 0; - -pci_release: - pci_release_regions(pdev); -pci_disable: - pci_disable_device(pdev); - return -EBUSY; -} - -static void fpga_pci_remove(struct pci_dev *pdev) -{ - platform_driver_unregister(&silverstone_drv); - platform_device_unregister(&silverstone_dev); - fpgafw_exit(); - pci_iounmap(pdev, fpga_dev.data_base_addr); - pci_release_regions(pdev); - pci_disable_device(pdev); - printk(KERN_INFO "FPGA PCIe driver remove OK.\n"); -}; - -static struct pci_driver pci_dev_ops = { - .name = FPGA_PCI_NAME, - .probe = fpga_pci_probe, - .remove = fpga_pci_remove, - .id_table = fpga_id_table, -}; - -enum { - READREG, - WRITEREG -}; - -struct fpga_reg_data { - uint32_t addr; - uint32_t value; -}; - -static long fpgafw_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { - int ret = 0; - struct fpga_reg_data data; - mutex_lock(&fpga_data->fpga_lock); - -#ifdef TEST_MODE - static uint32_t status_reg; -#endif - // Switch function to read and write. - switch (cmd) { - case READREG: - if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } - data.value = ioread32(fpga_dev.data_base_addr + data.addr); - if (copy_to_user((void __user*)arg , &data, sizeof(data)) != 0) { - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } -#ifdef TEST_MODE - if (data.addr == 0x1210) { - switch (status_reg) { - case 0x0000 : status_reg = 0x8000; - break; - - case 0x8080 : status_reg = 0x80C0; - break; - case 0x80C0 : status_reg = 0x80F0; - break; - case 0x80F0 : status_reg = 0x80F8; - break; - - } - iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); - } -#endif - - - break; - case WRITEREG: - if (copy_from_user(&data, (void __user*)arg, sizeof(data)) != 0) { - mutex_unlock(&fpga_data->fpga_lock); - return -EFAULT; - } - iowrite32(data.value, fpga_dev.data_base_addr + data.addr); - -#ifdef TEST_MODE - if (data.addr == 0x1204) { - status_reg = 0x8080; - iowrite32(status_reg, fpga_dev.data_base_addr + 0x1210); - } -#endif - - break; - default: - mutex_unlock(&fpga_data->fpga_lock); - return -EINVAL; - } - mutex_unlock(&fpga_data->fpga_lock); - return ret; -} - - -const struct file_operations fpgafw_fops = { - .owner = THIS_MODULE, - .unlocked_ioctl = fpgafw_unlocked_ioctl, -}; - - -static int fpgafw_init(void) { - printk(KERN_INFO "Initializing the switchboard driver\n"); - // Try to dynamically allocate a major number for the device -- more difficult but worth it - majorNumber = register_chrdev(0, DEVICE_NAME, &fpgafw_fops); - if (majorNumber < 0) { - printk(KERN_ALERT "Failed to register a major number\n"); - return majorNumber; - } - printk(KERN_INFO "Device registered correctly with major number %d\n", majorNumber); - - // Register the device class - fpgafwclass = class_create(THIS_MODULE, CLASS_NAME); - if (IS_ERR(fpgafwclass)) { // Check for error and clean up if there is - unregister_chrdev(majorNumber, DEVICE_NAME); - printk(KERN_ALERT "Failed to register device class\n"); - return PTR_ERR(fpgafwclass); - } - printk(KERN_INFO "Device class registered correctly\n"); - - // Register the device driver - fpgafwdev = device_create(fpgafwclass, NULL, MKDEV(majorNumber, 0), NULL, DEVICE_NAME); - if (IS_ERR(fpgafwdev)) { // Clean up if there is an error - class_destroy(fpgafwclass); // Repeated code but the alternative is goto statements - unregister_chrdev(majorNumber, DEVICE_NAME); - printk(KERN_ALERT "Failed to create the FW upgrade device node\n"); - return PTR_ERR(fpgafwdev); - } - printk(KERN_INFO "FPGA fw upgrade device node created correctly\n"); - return 0; -} - -static void fpgafw_exit(void) { - device_destroy(fpgafwclass, MKDEV(majorNumber, 0)); // remove the device - class_unregister(fpgafwclass); // unregister the device class - class_destroy(fpgafwclass); // remove the device class - unregister_chrdev(majorNumber, DEVICE_NAME); // unregister the major number - printk(KERN_INFO "Goodbye!\n"); -} - -int silverstone_init(void) -{ - int rc; - rc = pci_register_driver(&pci_dev_ops); - if (rc) - return rc; - return 0; -} - -void silverstone_exit(void) -{ - pci_unregister_driver(&pci_dev_ops); -} - -module_init(silverstone_init); -module_exit(silverstone_exit); - -MODULE_AUTHOR("Celestica Inc."); -MODULE_DESCRIPTION("Celestica Silverstone platform driver"); -MODULE_VERSION(MOD_VERSION); -MODULE_LICENSE("GPL"); diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/xcvr-cls.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/xcvr-cls.c new file mode 100644 index 0000000000..bc0da613ec --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/xcvr-cls.c @@ -0,0 +1,520 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * xcvr-cls.c - front panel port control. + * + * Pradchaya Phucharoen + * Copyright (C) 2019 Celestica Corp. + */ + +#include +#include +#include +#include +#include +#include +#include +#include "xcvr-cls.h" + +/* FPGA front panel */ +#define PORT_CTRL 0 +#define PORT_STATUS 0x4 +#define PORT_INT_STATUS 0x8 +#define PORT_INT_MASK 0xC + +/* + * Port control degister + * LPMOD : active high, RW + * RST : active low, RW + * TXDIS : active high, RW +*/ +#define CTRL_LPMOD BIT(6) +#define CTRL_RST_L BIT(4) +#define CTRL_TXDIS BIT(0) + +/* + * Port status register + * IRQ : active low, RO + * PRESENT : active low, RO, for QSFP + * TXFAULT : active high, RO + * RXLOS : active high, RO + * MODABS : active high, RO, for SFP +*/ +#define STAT_IRQ_L BIT(5) +#define STAT_PRESENT_L BIT(4) +#define STAT_TXFAULT BIT(2) +#define STAT_RXLOS BIT(1) +#define STAT_MODABS BIT(0) + +/* + * NOTE: Interrupt and mask must be expose as bitfeild. + * Because the registers of interrupt flags are read-clear. + * + * Port interrupt flag resgister + * INT_N : interrupt flag, set when INT_N is assert. + * PRESENT : interrupt flag, set when QSFP module plugin/plugout. + * RXLOS : interrupt flag, set when rxlos is assert. + * MODABS : interrupt flag, set when SFP module plugin/plugout. +*/ +#define INTR_INT_N BIT(5) +#define INTR_PRESENT BIT(4) +#define INTR_TXFAULT BIT(2) +#define INTR_RXLOS BIT(1) +#define INTR_MODABS BIT(0) + +/* + * Port interrupt mask register + * INT_N : active low + * PRESENT : active low + * RXLOS_INT : active low + * MODABS : active low +*/ +#define MASK_INT_N_L BIT(5) +#define MASK_PRESENT_L BIT(4) +#define MASK_TXFAULT_L BIT(2) +#define MASK_RXLOS_L BIT(1) +#define MASK_MODABS_L BIT(0) + + +/* + * port_data - optical port data + * @xcvr: xcvr memory accessor + * @name: port name + * @index: front panel port index starting from 1 + */ +struct port_data { + struct xcvr_priv *xcvr; + const char *name; + unsigned int index; +}; + +/* + * xcvr_priv - port xcvr private data + * @dev: device for reference + * @base: virtual base address + * @num_ports: number of front panel ports + * @fp_devs: list of front panel port devices + */ +struct xcvr_priv { + struct device* dev; + void __iomem *base; + int port_reg_size; + int num_ports; + struct device **fp_devs; +}; + +static inline void port_setreg(struct xcvr_priv *xcvr, int reg, int index, u8 value) +{ + return iowrite8(value, xcvr->base + reg + (index - 1) * xcvr->port_reg_size); +} + +static inline u8 port_getreg(struct xcvr_priv *xcvr, int reg, int index) +{ + return ioread8(xcvr->base + reg + (index - 1) * xcvr->port_reg_size); +} + +static ssize_t qsfp_modprsL_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_STATUS, index); + return sprintf(buf, "%d\n", (data & STAT_PRESENT_L)?1:0); +} + +static ssize_t qsfp_irqL_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_STATUS, index); + return sprintf(buf, "%d\n", (data & STAT_IRQ_L)?1:0); +} + +static ssize_t qsfp_lpmode_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_CTRL, index); + return sprintf(buf, "%d\n", (data & CTRL_LPMOD)?1:0); +} + +static ssize_t qsfp_lpmode_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + ssize_t status; + long value; + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + status = kstrtol(buf, 0, &value); + if (status == 0) { + data = port_getreg(port_data->xcvr, PORT_CTRL, index); + if (value == 0) + data &= ~CTRL_LPMOD; + else + data |= CTRL_LPMOD; + port_setreg(port_data->xcvr, PORT_CTRL, index, data); + status = size; + } + return status; +} + +static ssize_t qsfp_resetL_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_CTRL, index); + return sprintf(buf, "%d\n", (data & CTRL_RST_L)?1:0); +} + +static ssize_t qsfp_resetL_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + ssize_t status; + long value; + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + status = kstrtol(buf, 0, &value); + if (status == 0) { + data = port_getreg(port_data->xcvr, PORT_CTRL, index); + if (value == 0) + data &= ~CTRL_RST_L; + else + data |= CTRL_RST_L; + port_setreg(port_data->xcvr, PORT_CTRL, index, data); + status = size; + } + return status; +} + +static ssize_t sfp_modabs_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_STATUS, index); + return sprintf(buf, "%d\n", (data & STAT_MODABS)?1:0); +} + +static ssize_t sfp_txfault_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_STATUS, index); + return sprintf(buf, "%d\n", (data & STAT_TXFAULT)?1:0); +} + +static ssize_t sfp_rxlos_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_STATUS, index); + return sprintf(buf, "%d\n", (data & STAT_RXLOS)?1:0); +} + +static ssize_t sfp_txdisable_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_CTRL, index); + return sprintf(buf, "%d\n", (data & CTRL_TXDIS)?1:0); +} + +static ssize_t sfp_txdisable_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + ssize_t status; + long value; + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + status = kstrtol(buf, 0, &value); + if (status == 0) { + data = port_getreg(port_data->xcvr, PORT_CTRL, index); + if (value == 0) + data &= ~CTRL_TXDIS; + else + data |= CTRL_TXDIS; + port_setreg(port_data->xcvr, PORT_CTRL, index, data); + status = size; + } + return status; +} + +static ssize_t interrupt_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_INT_STATUS, index); + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t interrupt_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + ssize_t status; + long value; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + status = kstrtoul(buf, 0, &value); + if (status == 0) { + port_setreg(port_data->xcvr, PORT_INT_STATUS, index, value); + status = size; + } + return status; +} + +static ssize_t interrupt_mask_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + u8 data; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + data = port_getreg(port_data->xcvr, PORT_INT_MASK, index); + return sprintf(buf, "0x%2.2x\n", data); +} + +static ssize_t interrupt_mask_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + ssize_t status; + long value; + struct port_data *port_data = dev_get_drvdata(dev); + unsigned int index = port_data->index; + + status = kstrtoul(buf, 0, &value); + if (status == 0) { + port_setreg(port_data->xcvr, PORT_INT_MASK, index, value); + status = size; + } + return status; +} + +DEVICE_ATTR_RO(qsfp_modprsL); +DEVICE_ATTR_RO(qsfp_irqL); +DEVICE_ATTR_RW(qsfp_lpmode); +DEVICE_ATTR_RW(qsfp_resetL); + +DEVICE_ATTR_RO(sfp_modabs); +DEVICE_ATTR_RO(sfp_txfault); +DEVICE_ATTR_RO(sfp_rxlos); +DEVICE_ATTR_RW(sfp_txdisable); + +DEVICE_ATTR_RW(interrupt); +DEVICE_ATTR_RW(interrupt_mask); + +/* qsfp_attrs */ +static struct attribute *qsfp_attrs[] = { + &dev_attr_qsfp_modprsL.attr, + &dev_attr_qsfp_lpmode.attr, + &dev_attr_qsfp_resetL.attr, + &dev_attr_interrupt.attr, + &dev_attr_interrupt_mask.attr, + NULL +}; + +/* sfp_attrs */ +static struct attribute *sfp_attrs[] = { + &dev_attr_sfp_modabs.attr, + &dev_attr_sfp_txfault.attr, + &dev_attr_sfp_rxlos.attr, + &dev_attr_sfp_txdisable.attr, + &dev_attr_interrupt.attr, + &dev_attr_interrupt_mask.attr, + NULL +}; + +ATTRIBUTE_GROUPS(qsfp); +ATTRIBUTE_GROUPS(sfp); + +/* A single port device init */ +static struct device* init_port(struct device *dev, + struct xcvr_priv *xcvr, + struct port_info info, + const struct attribute_group **groups) +{ + struct port_data *new_data; + + new_data = devm_kzalloc(dev, sizeof(struct port_data), GFP_KERNEL); + if (!new_data) + return ERR_PTR(-ENOMEM); + + new_data->index = info.index; + new_data->name = info.name; + new_data->xcvr = xcvr; + + return devm_hwmon_device_register_with_groups(dev, + info.name, + new_data, + groups); +} + +static void xcvr_cleanup(struct xcvr_priv *xcvr) +{ + struct device *dev; + struct port_data *data; + int i; + + for (i = 0; i < xcvr->num_ports; i++){ + dev = xcvr->fp_devs[i]; + if (dev == NULL) + continue; + data = dev_get_drvdata(dev); + sysfs_remove_link(&xcvr->dev->kobj, data->name); + } +} + +static int cls_xcvr_probe(struct platform_device *pdev) +{ + + struct xcvr_priv *xcvr; + struct cls_xcvr_platform_data *pdata; + struct resource *res; + int ret; + int i; + + struct device **port_devs; + + xcvr = devm_kzalloc(&pdev->dev, sizeof(struct xcvr_priv), GFP_KERNEL); + if (!xcvr){ + ret = -ENOMEM; + goto err_exit; + } + + dev_set_drvdata(&pdev->dev, xcvr); + + /* mmap resource */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) { + xcvr->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(xcvr->base)){ + ret = PTR_ERR(xcvr->base); + goto err_exit; + } + } + + pdata = dev_get_platdata(&pdev->dev); + xcvr->dev = &pdev->dev; + + if (pdata) { + /* assign pdata */ + xcvr->num_ports = pdata->num_ports; + xcvr->port_reg_size = pdata->port_reg_size; + } + + /* alloc front panel device list */ + port_devs = devm_kzalloc(&pdev->dev, + xcvr->num_ports * sizeof(struct device*), + GFP_KERNEL); + if (!port_devs){ + ret = -ENOMEM; + goto err_exit; + } + + + if (pdata) { + /* create each device attrs group determined by type */ + for (i = 0; i < pdata->num_ports; i++) { + struct device *fp_dev; + + if (pdata->devices[i].type == SFP){ + fp_dev = init_port(&pdev->dev, + xcvr, + pdata->devices[i], + sfp_groups); + }else{ + fp_dev = init_port(&pdev->dev, + xcvr, + pdata->devices[i], + qsfp_groups); + } + if (IS_ERR(fp_dev)) { + dev_err(&pdev->dev, + "Failed to init port %s\n", + pdata->devices[i].name); + ret = PTR_ERR(fp_dev); + goto dev_clean_up; + } + + dev_info(&pdev->dev, + "Register port %s\n", + pdata->devices[i].name); + + WARN(sysfs_create_link(&pdev->dev.kobj, + &fp_dev->kobj, + pdata->devices[i].name), + "can't create symlink to %s\n", pdata->devices[i].name); + port_devs[i] = fp_dev; + fp_dev = NULL; + } + xcvr->fp_devs = port_devs; + } + + return 0; + +dev_clean_up: + xcvr_cleanup(xcvr); +err_exit: + return ret; + +} + + +static int cls_xcvr_remove(struct platform_device *pdev) +{ + struct xcvr_priv *xcvr = dev_get_drvdata(&pdev->dev); + xcvr_cleanup(xcvr); + return 0; +} + + +static struct platform_driver cls_xcvr_driver = { + .probe = cls_xcvr_probe, + .remove = cls_xcvr_remove, + .driver = { + .name = "cls-xcvr", + }, +}; + +module_platform_driver(cls_xcvr_driver); + +MODULE_AUTHOR("Pradchaya Phucharoen"); +MODULE_DESCRIPTION("Celestica xcvr control driver"); +MODULE_VERSION("0.0.1-3"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:cls-xcvr"); \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/xcvr-cls.h b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/xcvr-cls.h new file mode 100644 index 0000000000..7659a7c0e9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/xcvr-cls.h @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * xcvr-cls.h + * + * Pradchaya Phucharoen + * Copyright (C) 2019 Celestica Corp. + */ + +#ifndef _LINUX_I2C_CLS_H +#define _LINUX_I2C_CLS_H + +enum PORT_TYPE { + NONE = 0, + SFP, + QSFP +}; + +/* + * port_info - optical port info + * @index: front panel port index starting from 1 + * @typr: port type, see *PORT_TYPE* + */ +struct port_info { + const char *name; + unsigned int index; + enum PORT_TYPE type; +}; + +/* + * cls_xcvr_platform_data - port xcvr private data + * @port_reg_size: register range of each port + * @num_ports: number of front panel ports + * @devices: list of front panel port info + */ +struct cls_xcvr_platform_data { + unsigned int port_reg_size; + int num_ports; + struct port_info *devices; +}; + +#endif /* _LINUX_I2C_CLS_H */ \ No newline at end of file diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py index 1aa1c07198..207e08e542 100755 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/platform_sensors.py @@ -6,28 +6,39 @@ # The following data is support: # 1. Temperature sensors # 2. PSUs -# 3. Fan trays +# 3. Fan Drawers import sys import logging import subprocess -IPMI_SDR_CMD = ["ipmitool", "sdr", "elist"] +IPMI_SDR_CMD = ['/usr/bin/ipmitool', 'sdr', 'elist'] MAX_NUM_FANS = 7 MAX_NUM_PSUS = 2 +SENSOR_NAME = 0 +SENSOR_VAL = 4 + +sensor_dict = {} def ipmi_sensor_dump(cmd): ''' Execute ipmitool command return dump output exit if any error occur. ''' + global sensor_dict sensor_dump = '' + try: - sensor_dump = subprocess.check_output(cmd) + sensor_dump = subprocess.check_output(IPMI_SDR_CMD, universal_newlines=True) except subprocess.CalledProcessError as e: logging.error('Error! Failed to execute: {}'.format(cmd)) sys.exit(1) - return sensor_dump + + for line in sensor_dump.splitlines(): + sensor_info = line.split('|') + sensor_dict[sensor_info[SENSOR_NAME].strip()] = sensor_info[SENSOR_VAL].strip() + + return True def get_reading_by_name(sensor_name, sdr_elist_dump): ''' @@ -49,7 +60,8 @@ def get_reading_by_name(sensor_name, sdr_elist_dump): ''' found = '' - for line in sdr_elist_dump.split("\n"): + for line in sdr_elist_dump.splitlines(): + line = line.decode() if sensor_name in line: found = line.strip() break @@ -67,19 +79,18 @@ def get_reading_by_name(sensor_name, sdr_elist_dump): return found -def read_temperature_sensors(ipmi_sdr_elist): - - sensor_list = [ - ('TEMP_FAN_U52', 'Fan Tray Middle Temp'), - ('TEMP_FAN_U17', 'Fan Tray Right Temp'), - ('TEMP_SW_U52', 'Switchboard Left Inlet Temp'), - ('TEMP_SW_U16', 'Switchboard Right Inlet Temp'), - ('TEMP_BB_U3', 'Baseboard Temp'), - ('TEMP_CPU', 'CPU Internal Temp'), - ('TEMP_SW_Internal', 'ASIC Internal Temp'), - ('SW_U04_Temp', 'IR3595 Chip Left Temp'), - ('SW_U14_Temp', 'IR3595 Chip Right Temp'), - ('SW_U4403_Temp', 'IR3584 Chip Temp'), +def read_temperature_sensors(): + sensor_list = [\ + ('TEMP_FAN_U52', 'Fanboard Center Temp'),\ + ('TEMP_FAN_U17', 'Fanboard Right Temp'),\ + ('TEMP_SW_U52', 'Switchboard Left Temp'),\ + ('TEMP_SW_U16', 'Switchboard Right Temp'),\ + ('TEMP_BB_U3', 'Baseboard Temp'),\ + ('TEMP_CPU', 'CPU Internal Temp'),\ + ('TEMP_SW_Internal', 'ASIC Internal Temp'),\ + ('SW_U04_Temp', 'IR35215 Chip Left Temp'),\ + ('SW_U14_Temp', 'IR35215 Chip Right Temp'),\ + ('SW_U4403_Temp', 'IR3584 Chip Temp'),\ ] output = '' @@ -90,20 +101,18 @@ def read_temperature_sensors(ipmi_sdr_elist): output += "Temperature Sensors\n" output += "Adapter: IPMI adapter\n" for sensor in sensor_list: - reading = get_reading_by_name(sensor[0],ipmi_sdr_elist) - output += sensor_format.format('{}:'.format(sensor[1]), - reading, + output += sensor_format.format('{}:'.format(sensor[1]),\ + sensor_dict[sensor[0]],\ width=str(max_name_width+1)) output += '\n' return output +def read_fan_sensors(num_fans): -def read_fan_sensors(num_fans, ipmi_sdr_elist): - - sensor_list = [ - ('Fan{}_Status', 'Status'), - ('Fan{}_Front', 'Fan {} front'), - ('Fan{}_Rear', 'Fan {} rear'), + sensor_list = [\ + ('Fan{}_Status', 'Fan Drawer {} Status'),\ + ('Fan{}_Front', 'Fan {} front'),\ + ('Fan{}_Rear', 'Fan {} rear'),\ ] output = '' @@ -111,33 +120,31 @@ def read_fan_sensors(num_fans, ipmi_sdr_elist): # Find max length of sensor calling name max_name_width = max(len(sensor[1]) for sensor in sensor_list) - output += "Fan Trays\n" + output += "Fan Drawers\n" output += "Adapter: IPMI adapter\n" for fan_num in range(1, num_fans+1): for sensor in sensor_list: ipmi_sensor_name = sensor[0].format(fan_num) display_sensor_name = sensor[1].format(fan_num) - reading = get_reading_by_name(ipmi_sensor_name, ipmi_sdr_elist) - output += sensor_format.format('{}:'.format(display_sensor_name), - reading, + output += sensor_format.format('{}:'.format(display_sensor_name),\ + sensor_dict[ipmi_sensor_name],\ width=str(max_name_width+1)) output += '\n' return output +def read_psu_sensors(num_psus): -def read_psu_sensors(num_psus, ipmi_sdr_elist): - - sensor_list = [ - ('PSU{}_Status', 'PSU {} Status'), - ('PSU{}_Fan', 'PSU {} Fan'), - ('PSU{}_VIn', 'PSU {} Input Voltag'), - ('PSU{}_CIn', 'PSU {} Input Current'), - ('PSU{}_PIn', 'PSU {} Input Power'), - ('PSU{}_Temp1', 'PSU {} Temp1'), - ('PSU{}_Temp2', 'PSU {} Temp2'), - ('PSU{}_VOut', 'PSU {} Output Voltag'), - ('PSU{}_COut', 'PSU {} Output Current'), - ('PSU{}_POut', 'PSU {} Output Power'), + sensor_list = [\ + ('PSU{}_Status', 'PSU {} Status'),\ + ('PSU{}_Fan', 'PSU {} Fan 1'),\ + ('PSU{}_VIn', 'PSU {} Input Voltage'),\ + ('PSU{}_CIn', 'PSU {} Input Current'),\ + ('PSU{}_PIn', 'PSU {} Input Power'),\ + ('PSU{}_Temp1', 'PSU {} Ambient Temp'),\ + ('PSU{}_Temp2', 'PSU {} Hotspot Temp'),\ + ('PSU{}_VOut', 'PSU {} Output Voltage'),\ + ('PSU{}_COut', 'PSU {} Output Current'),\ + ('PSU{}_POut', 'PSU {} Output Power'),\ ] output = '' @@ -151,22 +158,21 @@ def read_psu_sensors(num_psus, ipmi_sdr_elist): for sensor in sensor_list: ipmi_sensor_name = sensor[0].format(psu_num) display_sensor_name = sensor[1].format(psu_num) - reading = get_reading_by_name(ipmi_sensor_name, ipmi_sdr_elist) - output += sensor_format.format('{}:'.format(display_sensor_name), - reading, + output += sensor_format.format('{}:'.format(display_sensor_name),\ + sensor_dict[ipmi_sensor_name],\ width=str(max_name_width+1)) output += '\n' return output - def main(): output_string = '' - ipmi_sdr_elist = ipmi_sensor_dump(IPMI_SDR_CMD) - output_string += read_temperature_sensors(ipmi_sdr_elist) - output_string += read_psu_sensors(MAX_NUM_PSUS, ipmi_sdr_elist) - output_string += read_fan_sensors(MAX_NUM_FANS, ipmi_sdr_elist) - print(output_string) + if ipmi_sensor_dump(IPMI_SDR_CMD): + output_string += read_temperature_sensors() + output_string += read_psu_sensors(MAX_NUM_PSUS) + output_string += read_fan_sensors(MAX_NUM_FANS) + + print(output_string) if __name__ == '__main__': diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors index 405d92c2b3..5d740a9eb7 100755 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/sensors @@ -8,4 +8,4 @@ if [ -t 1 ] ; then fi docker exec -$DOCKER_EXEC_FLAGS pmon sensors "$@" -docker exec -$DOCKER_EXEC_FLAGS pmon platform_sensors.py "$@" +docker exec -$DOCKER_EXEC_FLAGS pmon python3 /usr/bin/platform_sensors.py "$@" diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/silverstone_platform_shutdown.sh b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/silverstone_platform_shutdown.sh new file mode 100755 index 0000000000..973c90378d --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/scripts/silverstone_platform_shutdown.sh @@ -0,0 +1,26 @@ +#!/bin/bash +REBOOT_CAUSE_DIR="/host/reboot-cause" +HW_REBOOT_CAUSE_FILE="/host/reboot-cause/hw-reboot-cause.txt" +REBOOT_TIME=$(date) + +if [ $# -ne 1 ]; then + echo "Require reboot type" + exit 1 +fi + +if [ ! -d "$REBOOT_CAUSE_DIR" ]; then + mkdir $REBOOT_CAUSE_DIR +fi + +echo "Reason:$1,Time:${REBOOT_TIME}" > ${HW_REBOOT_CAUSE_FILE} + +# Best effort to write buffered data onto the disk +sync ; sync ; sync ; sleep 3 + +# BMC cold power-cyle +ipmitool chassis power cycle &> /dev/null + +# System should reboot by now and avoid the script returning to caller +sleep 10 + +exit 0 diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py index 20a2b6d106..7da0814059 100644 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/setup.py @@ -1,8 +1,5 @@ from setuptools import setup -DEVICE_NAME = 'celestica' -HW_SKU = 'x86_64-cel_silverstone-r0' - setup( name='sonic-platform', version='1.0', @@ -17,7 +14,7 @@ setup( 'sonic_platform', ], package_dir={ - 'sonic_platform': '../../../../device/{}/{}/sonic_platform'.format(DEVICE_NAME, HW_SKU)}, + 'sonic_platform': 'sonic_platform'}, classifiers=[ 'Development Status :: 3 - Alpha', 'Environment :: Plugins', diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/__init__.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/__init__.py new file mode 100644 index 0000000000..d3c24cb008 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/__init__.py @@ -0,0 +1,2 @@ +__all__ = ["platform", "chassis"] +from sonic_platform import platform diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/chassis.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/chassis.py new file mode 100644 index 0000000000..5c43d9889c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/chassis.py @@ -0,0 +1,436 @@ +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the Chassis information which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.chassis_base import ChassisBase + from sonic_platform_base.sonic_sfp.sfputilhelper import SfpUtilHelper + from sonic_py_common import device_info + from .helper import APIHelper + import time + import os + import re + import shutil +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN_TRAY = 7 +NUM_FAN = 2 +NUM_PSU = 2 +NUM_THERMAL = 14 +NUM_SFP = 32 +NUM_COMPONENT = 10 + +IPMI_OEM_NETFN = "0x3A" +IPMI_GET_REBOOT_CAUSE = "0x03 0x00 0x01 0x06" + +IPMI_SET_SYS_LED_CMD = "0x07 0x00 {}" +IPMI_GET_SYS_LED_CMD = "0x08 0x00" + +LPC_GETREG_PATH = "/sys/bus/platform/devices/baseboard-lpc/getreg" +LPC_SETREG_PATH = "/sys/bus/platform/devices/baseboard-lpc/setreg" +LPC_STATUS_LED_REG = "0xA162" + +ORG_HW_REBOOT_CAUSE_FILE="/host/reboot-cause/hw-reboot-cause.txt" +TMP_HW_REBOOT_CAUSE_FILE="/tmp/hw-reboot-cause.txt" + +class Chassis(ChassisBase): + """Platform-specific Chassis class""" + + #led color status + SYSLED_COLOR_VAL_MAP = { + 'off': '0xff', + 'green': '0xdc', + 'amber': '0xec', + 'green_blink_1hz': '0xdd', + 'green_blink_4hz': '0xde', + 'amber_blink_1hz': '0xed', + 'amber_blink_4hz': '0xee', + 'green_amber_1hz': '0xcd', + 'green_amber_4hz': '0xce' + } + + SYSLED_VAL_COLOR_DESC_MAP = { + "0xff": "off", + "0xdc": "green", + "0xec": "amber", + "0xdd": "green blinking 1Hz", + "0xde": "green blinking 4Hz", + "0xed": "amber blinking 1Hz", + "0xee": "amber blinking 4Hz", + "0xcd": "green & amber alternate 1Hz", + "0xce": "green & amber alternate 4Hz" + } + + def __init__(self): + ChassisBase.__init__(self) + self._api_helper = APIHelper() + self.sfp_module_initialized = False + self._sfp_list = [] + self.sfp_status_dict = {} + self._watchdog = None + self._airflow_direction = None + + self.__initialize_eeprom() + self.is_host = self._api_helper.is_host() + + self.__initialize_fan() + self.__initialize_psu() + self.__initialize_thermals() + self.__initialize_components() + + def __initialize_sfp(self): + sfputil_helper = SfpUtilHelper() + port_config_file_path = device_info.get_path_to_port_config_file() + sfputil_helper.read_porttab_mappings(port_config_file_path, 0) + + #from sonic_platform.sfp import Sfp + from sonic_platform.sfp import Sfp + for index in range(0, NUM_SFP): + #sfp = Sfp(index, sfputil_helper.logical[index]) + sfp = Sfp(index, sfputil_helper.physical_to_logical[index + 1]) + self._sfp_list.append(sfp) + self.sfp_status_dict[sfp.index] = '1' if sfp.get_presence() else '0' + self.sfp_module_initialized = True + + def __initialize_psu(self): + from sonic_platform.psu import Psu + for index in range(0, NUM_PSU): + psu = Psu(index) + self._psu_list.append(psu) + + def __initialize_fan(self): + from sonic_platform.fan_drawer import FanDrawer + for i in range(NUM_FAN_TRAY): + fandrawer = FanDrawer(i) + self._fan_drawer_list.append(fandrawer) + self._fan_list.extend(fandrawer._fan_list) + + def __initialize_thermals(self): + from sonic_platform.thermal import Thermal + # airflow = self.__get_air_flow() + for index in range(0, NUM_THERMAL): + thermal = Thermal(index) + self._thermal_list.append(thermal) + + def __initialize_eeprom(self): + from sonic_platform.eeprom import Eeprom + self._eeprom = Eeprom() + + def __initialize_components(self): + from sonic_platform.component import Component + for index in range(0, NUM_COMPONENT): + component = Component(index) + self._component_list.append(component) + + def initizalize_system_led(self): + pass + + 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' + """ + return self._eeprom.get_mac() + + def get_revision(self): + """ + Retrieves the hardware revision for the chassis + Returns: + A string containing the hardware revision for this chassis. + """ + return self._eeprom.get_revision() + + def get_serial(self): + """ + Retrieves the hardware serial number for the chassis + Returns: + A string containing the hardware serial number for this chassis. + """ + return self._eeprom.get_serial() + + def get_system_eeprom_info(self): + """ + Retrieves the full content of system EEPROM information for the chassis + Returns: + A dictionary where keys are the type code defined in + OCP ONIE TlvInfo EEPROM format and values are their corresponding + values. + """ + return self._eeprom.get_eeprom() + + def get_reboot_cause(self): + """ + Retrieves the cause of the previous reboot + + Returns: + A tuple (string, string) where the first element is a string + containing the cause of the previous reboot. This string must be + one of the predefined strings in this class. If the first string + is "REBOOT_CAUSE_HARDWARE_OTHER", the second string can be used + to pass a description of the reboot cause. + """ + + status, raw_cause = self._api_helper.ipmi_raw( + IPMI_OEM_NETFN, IPMI_GET_REBOOT_CAUSE) + hx_cause = raw_cause.split()[0] if status and len( + raw_cause.split()) > 0 else 00 + + # This tmp copy is to retain the reboot-cause only for the current boot + if os.path.isfile(ORG_HW_REBOOT_CAUSE_FILE): + shutil.move(ORG_HW_REBOOT_CAUSE_FILE, TMP_HW_REBOOT_CAUSE_FILE) + + if hx_cause == "77" and os.path.isfile(TMP_HW_REBOOT_CAUSE_FILE): + with open(TMP_HW_REBOOT_CAUSE_FILE) as hw_cause_file: + reboot_info = hw_cause_file.readline().rstrip('\n') + match = re.search(r'Reason:(.*),Time:(.*)', reboot_info) + if match is not None: + if match.group(1) == 'system': + return (self.REBOOT_CAUSE_NON_HARDWARE, 'System cold reboot') + + reboot_cause = { + "00": self.REBOOT_CAUSE_HARDWARE_OTHER, + "11": self.REBOOT_CAUSE_POWER_LOSS, + "22": self.REBOOT_CAUSE_NON_HARDWARE, + "33": self.REBOOT_CAUSE_NON_HARDWARE, + "44": self.REBOOT_CAUSE_NON_HARDWARE, + "55": self.REBOOT_CAUSE_HARDWARE_OTHER, + "66": self.REBOOT_CAUSE_WATCHDOG, + "77": self.REBOOT_CAUSE_POWER_LOSS, + "88": self.REBOOT_CAUSE_WATCHDOG + }.get(hx_cause, self.REBOOT_CAUSE_HARDWARE_OTHER) + + description = { + "00": "Hardware Reason", + "11": "Power On Reset", + "22": "Soft-Set CPU Warm Reset", + "33": "Soft-Set CPU Cold Reset", + "44": "CPU Warm Reset", + "55": "CPU Cold Reset", + "66": "GPIO Watchdog Reset", + "77": "Power Cycle Reset", + "88": "Hardware Watchdog Reset" + }.get(hx_cause, "Unknown reason") + + return (reboot_cause, description) + + def get_change_event(self, timeout=0): + """ + Returns a nested dictionary containing all devices which have + experienced a change at chassis level + Args: + timeout: Timeout in milliseconds (optional). If timeout == 0, + this method will block until a change is detected. + Returns: + (bool, dict): + - True if call successful, False if not; + - A nested dictionary where key is a device type, + value is a dictionary with key:value pairs in the format of + {'device_id':'device_event'}, + where device_id is the device ID for this device and + device_event, + status='1' represents device inserted, + status='0' represents device removed. + 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. + """ + # SFP event + if not self.sfp_module_initialized: + self.__initialize_sfp() + + sfp_dict = {} + + SFP_REMOVED = '0' + SFP_INSERTED = '1' + + SFP_PRESENT = True + SFP_ABSENT = False + + start_time = time.time() + time_period = timeout/float(1000) #Convert msecs to secs + + while time.time() < (start_time + time_period) or timeout == 0: + for sfp in self._sfp_list: + port_idx = sfp.index + if self.sfp_status_dict[port_idx] == SFP_REMOVED and \ + sfp.get_presence() == SFP_PRESENT: + sfp_dict[port_idx] = SFP_INSERTED + self.sfp_status_dict[port_idx] = SFP_INSERTED + elif self.sfp_status_dict[port_idx] == SFP_INSERTED and \ + sfp.get_presence() == SFP_ABSENT: + sfp_dict[port_idx] = SFP_REMOVED + self.sfp_status_dict[port_idx] = SFP_REMOVED + + if sfp_dict: + return True, {'sfp':sfp_dict} + + time.sleep(0.5) + + return True, {'sfp':{}} # Timeout + + ############################################################## + ######################## SFP methods ######################### + ############################################################## + + def get_num_sfps(self): + """ + Retrieves the number of sfps available on this chassis + Returns: + An integer, the number of sfps available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return len(self._sfp_list) + + def get_all_sfps(self): + """ + Retrieves all sfps available on this chassis + Returns: + A list of objects derived from SfpBase representing all sfps + available on this chassis + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + + return self._sfp_list + + def get_sfp(self, index): + """ + Retrieves sfp represented by (1-based) index + Args: + index: An integer, the index (1-based) of the sfp to retrieve. + The index should be the sequence of a physical port in a chassis, + starting from 1. + For example, 1 for Ethernet0, 2 for Ethernet4 and so on. + Returns: + An object dervied from SfpBase representing the specified sfp + """ + if not self.sfp_module_initialized: + self.__initialize_sfp() + return super(Chassis, self).get_sfp(index-1) + + ############################################################## + ####################### Other methods ######################## + ############################################################## + + def get_watchdog(self): + """ + Retreives hardware watchdog device on this chassis + Returns: + An object derived from WatchdogBase representing the hardware + watchdog device + """ + if self._watchdog is None: + from sonic_platform.watchdog import Watchdog + self._watchdog = Watchdog() + + return self._watchdog + + def get_thermal_manager(self): + from .thermal_manager import ThermalManager + return ThermalManager + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._api_helper.hwsku + + def get_presence(self): + """ + Retrieves the presence of the Chassis + Returns: + bool: True if Chassis is present, False if not + """ + return True + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._eeprom.get_pn() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return True + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return -1 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return False + + def set_status_led(self, color): + """ + Sets the state of the PSU status LED + Args: + color: A string representing the color with which to set the PSU status LED + Note: Only support green and off + Returns: + bool: True if status LED state is set successfully, False if not + """ + color_val = self.SYSLED_COLOR_VAL_MAP.get(color) + if color_val == None: + return False + + status = self._api_helper.lpc_setreg(LPC_SETREG_PATH, LPC_STATUS_LED_REG, color_val) + return status + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + color_val = self._api_helper.lpc_getreg(LPC_GETREG_PATH, LPC_STATUS_LED_REG) + color = self.SYSLED_VAL_COLOR_DESC_MAP.get(color_val, "N/A") + return color + + def get_airflow_direction(self): + if self._airflow_direction == None: + try: + vendor_extn = self._eeprom.get_vendor_extn() + airflow_type = vendor_extn.split()[2][2:4] # Either 0xFB or 0xBF + if airflow_type == 'FB': + direction = 'exhaust' + elif airflow_type == 'BF': + direction = 'intake' + else: + direction = 'N/A' + except (AttributeError, IndexError): + direction = 'N/A' + + self._airflow_direction = direction + + return self._airflow_direction diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/component.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/component.py new file mode 100644 index 0000000000..0e0f2b505c --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/component.py @@ -0,0 +1,182 @@ +############################################################################# +# Celestica +# +# Component contains an implementation of SONiC Platform Base API and +# provides the components firmware management function +# +############################################################################# + +import json +import os.path +import subprocess +import re + +try: + from sonic_platform_base.component_base import ComponentBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NAME_IDX = 0 +DESC_IDX = 1 +VER_API_IDX = 2 + +BASE_CPLD_VER_CMD = "0x03 0x00 0x01 0x00" +FAN_CPLD_VER_CMD = "0x03 0x01 0x01 0x00" +BIOS_VER_PATH = "/sys/class/dmi/id/bios_version" +BMC_VER_CMD = "ipmitool mc info | grep 'Firmware Revision'" +ONIE_VER_CMD = "cat /host/machine.conf" +SSD_VER_CMD = "smartctl -i /dev/sda" +BASE_GETREG_PATH = "/sys/devices/platform/baseboard-lpc/getreg" +MEM_PCI_RESOURCE = "/sys/bus/pci/devices/0000:09:00.0/resource0" +FPGA_VER_MEM_OFFSET = 0 + +NETFN = "0x3A" +COME_CPLD_VER_REG = "0xA1E0" + +class Component(ComponentBase): + """Platform-specific Component class""" + + DEVICE_TYPE = "component" + + def __init__(self, component_index): + COMPONENT_LIST = [ + ("BIOS", "Basic Input/Output System", self.__get_bios_ver), + ("ONIE", "Open Network Install Environment", self.__get_onie_ver), + ("BMC", "Baseboard Management Controller", self.__get_bmc_ver), + ("FPGA", "FPGA for transceiver EEPROM access and other component I2C access", self.__get_fpga_ver), + ("CPLD COMe", "COMe board CPLD", self.__get_come_cpld_ver), + ("CPLD BASE", "CPLD for board functions and watchdog", self.__get_cpld_ver_from_bmc), + ("CPLD SW1", "CPLD for port control QSFP(1-16)", self.__get_sw_cpld1_ver), + ("CPLD SW2", "CPLD for port control QSFP(17-32) SFP(33-34)", self.__get_sw_cpld2_ver), + ("CPLD FAN", "CPLD for fan control and status", self.__get_cpld_ver_from_bmc), + ("SSD", "Solid State Drive - {}", self.__get_ssd_ver) + ] + self.index = component_index + self.name = COMPONENT_LIST[self.index][NAME_IDX] + self.description = COMPONENT_LIST[self.index][DESC_IDX] + self.__get_version = COMPONENT_LIST[self.index][VER_API_IDX] + self._api_helper = APIHelper() + + def __i2c_get(self, bus, i2caddr, offset): + try: + return int(subprocess.check_output(['/usr/sbin/i2cget', '-y', '-f', str(bus), str(i2caddr), str(offset)]), 16) + except (FileNotFoundError, subprocess.CalledProcessError): + return -1 + + def __get_bios_ver(self): + return self._api_helper.read_txt_file(BIOS_VER_PATH) + + def __get_onie_ver(self): + onie_ver = "N/A" + status, raw_onie_data = self._api_helper.run_command(ONIE_VER_CMD) + if status: + ret = re.search(r"(?<=onie_version=).+[^\n]", raw_onie_data) + if ret != None: + onie_ver = ret.group(0) + return onie_ver + + def __get_bmc_ver(self): + bmc_ver = "Unknown" + status, raw_bmc_data = self._api_helper.run_command(BMC_VER_CMD) + if status: + bmc_ver_data = raw_bmc_data.split(":") + bmc_ver = bmc_ver_data[-1].strip() if len( + bmc_ver_data) > 1 else bmc_ver + return bmc_ver + + def __get_fpga_ver(self): + fpga_ver = "Unknown" + status, reg_val = self._api_helper.pci_get_value( + MEM_PCI_RESOURCE, FPGA_VER_MEM_OFFSET) + if status: + major = reg_val[0] >> 16 + minor = int(bin(reg_val[0])[16:32], 2) + fpga_ver = '{}.{}'.format(major, minor) + return fpga_ver + + def __get_come_cpld_ver(self): + cpld_ver_str = self._api_helper.lpc_getreg(BASE_GETREG_PATH, COME_CPLD_VER_REG) + if not cpld_ver_str: + return "N/A" + + cpld_ver = int(cpld_ver_str, 16) + return "{:x}.{:x}".format((cpld_ver >> 4) & 0xF, cpld_ver & 0xF) + + def __get_cpld_ver_from_bmc(self): + cpld_ver = "N/A" + cmd = BASE_CPLD_VER_CMD + + if self.name == "CPLD FAN": + cmd = FAN_CPLD_VER_CMD + + (rc, op) = self._api_helper.ipmi_raw(NETFN, cmd) + if rc and len(op) == 2: + cpld_ver = op[0] + '.' + op[1] + + return cpld_ver + + def __get_sw_cpld1_ver(self): + val = self.__i2c_get(4, 0x30, 0) + if val != -1: + return '{:x}.{:x}'.format((val >> 4) & 0xf, val & 0xf) + else: + return 'N/A' + + def __get_sw_cpld2_ver(self): + val = self.__i2c_get(4, 0x31, 0) + if val != -1: + return '{:x}.{:x}'.format((val >> 4) & 0xf, val & 0xf) + else: + return 'N/A' + + def __get_ssd_ver(self): + ssd_ver = "N/A" + status, raw_ssd_data = self._api_helper.run_command(SSD_VER_CMD) + if status: + ret = re.search(r"Firmware Version: +(.*)[^\\]", raw_ssd_data) + if ret != None: + ssd_ver = ret.group(1) + return ssd_ver + + def __get_ssd_model(self): + model = "N/A" + + status, raw_ssd_data = self._api_helper.run_command(SSD_VER_CMD) + if status: + ret = re.search(r"Device Model: +(.*)[^\\]", raw_ssd_data) + if ret != None: + try: + model = ret.group(1) + except (IndexError): + pass + + return model + + def get_name(self): + """ + Retrieves the name of the component + Returns: + A string containing the name of the component + """ + return self.name + + def get_description(self): + """ + Retrieves the description of the component + Returns: + A string containing the description of the component + """ + # For SSD get the model name from device + if self.get_name() == "SSD": + return self.description.format(self.__get_ssd_model()) + + return self.description + + def get_firmware_version(self): + """ + Retrieves the firmware version of module + Returns: + string: The firmware versions of the module + """ + return self.__get_version() diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/eeprom.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/eeprom.py new file mode 100644 index 0000000000..ed5891f4f5 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/eeprom.py @@ -0,0 +1,123 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Platform and model specific eeprom subclass, inherits from the base class, +# and provides the followings: +# - the eeprom format definition +# - specific encoder/decoder if there is special need +############################################################################# + +try: + import os + import sys + import re + import json + import fcntl + + if sys.version_info.major == 3: + from io import StringIO + else: + from cStringIO import StringIO + + from sonic_platform_base.sonic_eeprom import eeprom_tlvinfo +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +NULL = 'N/A' +EEPROM_TMP_FILE = '/tmp/eeprom_dump.json' + +class Eeprom(eeprom_tlvinfo.TlvInfoDecoder): + + EEPROM_DECODE_HEADLINES = 6 + + def __init__(self): + self._eeprom_path = "/sys/class/i2c-adapter/i2c-0/0-0056/eeprom" + super(Eeprom, self).__init__(self._eeprom_path, 0, '', True) + self._eeprom = self._load_eeprom() + + def __parse_output(self, decode_output): + decode_output.replace('\0', '') + lines = decode_output.split('\n') + lines = lines[self.EEPROM_DECODE_HEADLINES:] + _eeprom_info_dict = dict() + + for line in lines: + try: + match = re.search('(0x[0-9a-fA-F]{2})\s+\d+\s+(.+)', line) + if match is not None: + idx = match.group(1) + value = match.group(2).rstrip('\0') + + _eeprom_info_dict[idx] = value + except Exception: + pass + return _eeprom_info_dict + + def _load_eeprom(self): + eeprom_dict = {} + + if os.path.exists(EEPROM_TMP_FILE): + with open(EEPROM_TMP_FILE, 'r') as fd: + eeprom_dict = json.load(fd) + + return eeprom_dict + + original_stdout = sys.stdout + sys.stdout = StringIO() + rv = -1 + try: + rv = self.read_eeprom_db() + except BaseException: + pass + + if rv == 0: + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + eeprom_dict = self.__parse_output(decode_output) + else: + e = self.read_eeprom() + if e is None: + sys.stdout = original_stdout + return {} + + self.decode_eeprom(e) + decode_output = sys.stdout.getvalue() + sys.stdout = original_stdout + + (is_valid, valid_crc) = self.is_checksum_valid(e) + if not is_valid: + return {} + + eeprom_dict = self.__parse_output(decode_output) + + if len(eeprom_dict) != 0: + with open(EEPROM_TMP_FILE, 'w') as fd: + fcntl.flock(fd, fcntl.LOCK_EX) + json.dump(eeprom_dict, fd) + fcntl.flock(fd, fcntl.LOCK_UN) + + return eeprom_dict + + def get_eeprom(self): + return self._eeprom + + def get_product(self): + return self._eeprom.get('0x21', NULL) + + def get_pn(self): + return self._eeprom.get('0x22', NULL) + + def get_serial(self): + return self._eeprom.get('0x23', NULL) + + def get_mac(self): + return self._eeprom.get('0x24', NULL) + + def get_revision(self): + return self._eeprom.get('0x26', NULL) + + def get_vendor_extn(self): + return self._eeprom.get('0xFD', NULL) diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/fan.py similarity index 51% rename from device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py rename to platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/fan.py index 1a18eed9c8..30ef3d934b 100644 --- a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/fan.py +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/fan.py @@ -17,37 +17,36 @@ except ImportError as e: raise ImportError(str(e) + "- required module not found") -FAN_NAME_LIST = ["FAN-1F", "FAN-1R", "FAN-2F", "FAN-2R", "FAN-3F", "FAN-3R", - "FAN-4F", "FAN-4R", "FAN-5F", "FAN-5R", "FAN-6F", "FAN-6R", "FAN-7F", "FAN-7R"] - IPMI_OEM_NETFN = "0x3A" IPMI_SENSOR_NETFN = "0x04" IPMI_FAN_SPEED_CMD = "0x2D {}" IPMI_AIR_FLOW_CMD = "0x0A {}" IPMI_FAN_PRESENT_CMD = "0x06 0x03 {}" +IPMI_FAN_SPEED_CPLD_CMD = "0x03 0x01 0x01 {}" IPMI_SET_FAN_LED_CMD = "0x07 {} {}" IPMI_GET_FAN_LED_CMD = "0x08 {}" -IPMI_SET_PWM = "0x03 0x01 0x02 {} {}" -IPMI_FRU_MODEL_KEY = "Board Part Number" -IPMI_FRU_SERIAL_KEY = "Board Serial" +FAN_NAME_TEMPLATE = "{}Fan{}{}" -MAX_OUTLET = 24700 -MAX_INLET = 29700 -SPEED_TOLERANCE = 10 +FAN_FRONT_MAX_SPEED = 24700 +FAN_REAR_MAX_SPEED = 29700 +FAN_PSU_MAX_SPEED = 26500 +FAN_SPEED_TOLERANCE = 25 -FAN1_FRONT_SS_ID = "0x0D" -FAN1_REAR_SS_ID = "0x45" +CPLD_REG_FANTRAY_BASE = 0x22 +FAN_FRONT_SID_BASE = 0x0D # IPMI Sensor ID +FAN_REAR_SID_BASE = 0x45 # IPMI Sensor ID +FAN_FRU_ID_BASE = 6 +PSU_FRU_ID_BASE = 3 +PSU_FAN_SID_BASE = {\ + 0: 0x33,\ + 1: 0x3D\ +} FAN_LED_OFF_CMD = "0x00" FAN_LED_GREEN_CMD = "0x01" FAN_LED_RED_CMD = "0x02" FAN1_LED_CMD = "0x04" -FAN_PWM_REGISTER_START = 0x22 -FAN_PWM_REGISTER_STEP = 0x10 -FAN1_FRU_ID = 6 - -NUM_OF_FAN_TRAY = 7 -PSU_FAN1_FRONT_SS_ID = "0x33" +NUM_FAN_TRAY = 7 class Fan(FanBase): @@ -58,10 +57,24 @@ class Fan(FanBase): self.fan_index = fan_index self.fan_tray_index = fan_tray_index self.is_psu_fan = is_psu_fan + self.name = None if self.is_psu_fan: self.psu_index = psu_index + self.index = NUM_FAN_TRAY * 2 + self.psu_index + self.max_speed = FAN_PSU_MAX_SPEED + self.sid_offset = PSU_FAN_SID_BASE[self.psu_index] + else: + self.index = self.fan_tray_index * 2 + self.fan_index + if fan_index % 2 == 0: + self.is_front = True + self.sid_offset = FAN_FRONT_SID_BASE + self.fan_tray_index + self.max_speed = FAN_FRONT_MAX_SPEED + else: + self.is_front = False + self.sid_offset = FAN_REAR_SID_BASE + self.fan_tray_index + self.max_speed = FAN_REAR_MAX_SPEED + self._api_helper = APIHelper() - self.index = self.fan_tray_index * 2 + self.fan_index def get_direction(self): """ @@ -70,13 +83,30 @@ class Fan(FanBase): A string, either FAN_DIRECTION_INTAKE or FAN_DIRECTION_EXHAUST depending on fan direction """ - direction = self.FAN_DIRECTION_EXHAUST - fan_direction_key = hex(self.fan_tray_index) if not self.is_psu_fan else hex( - self.psu_index + NUM_OF_FAN_TRAY) - status, raw_flow = self._api_helper.ipmi_raw( - IPMI_OEM_NETFN, IPMI_AIR_FLOW_CMD.format(fan_direction_key)) - if status and raw_flow == "01": - direction = self.FAN_DIRECTION_INTAKE + direction = self.FAN_DIRECTION_NOT_APPLICABLE + + if not self.is_psu_fan: + offset = hex(self.fan_tray_index) + else: + offset = hex(NUM_FAN_TRAY + self.psu_index) + + status, output = self._api_helper.ipmi_raw(IPMI_OEM_NETFN,\ + IPMI_AIR_FLOW_CMD.format(offset)) + if status: + if output == "00": + direction = self.FAN_DIRECTION_EXHAUST + elif output == "01": + direction = self.FAN_DIRECTION_INTAKE + elif self.is_psu_fan: + # Trying to deduce from PSU model + status, output = self._api_helper.ipmi_fru_id(PSU_FRU_ID_BASE + self.fan_tray_index, + "Board Part Number") + if status and output: + model = output.split(':')[-1].strip() + if model == "TDPS1500AB7C": + direction = self.FAN_DIRECTION_INTAKE + elif model == "TDPS1500AB6E": + direction = self.FAN_DIRECTION_EXHAUST return direction @@ -86,24 +116,20 @@ class Fan(FanBase): Returns: An integer, the percentage of full fan speed, in the range 0 (off) to 100 (full speed) - - Note: - M = 150 - Max F2B = 24700 RPM - Max B2F = 29700 RPM """ + speed = 0 - max_rpm = MAX_OUTLET if self.fan_index % 2 == 0 else MAX_INLET - fan1_ss_start = FAN1_FRONT_SS_ID if self.fan_index % 2 == 0 else FAN1_REAR_SS_ID + if not self.is_psu_fan: + multiplier = 150.0 + else: + multiplier = 200.0 - ss_id = hex(int(fan1_ss_start, 16) + self.fan_tray_index) if not self.psu_index else hex( - int(PSU_FAN1_FRONT_SS_ID, 16) + self.fan_tray_index) - status, raw_ss_read = self._api_helper.ipmi_raw( - IPMI_SENSOR_NETFN, IPMI_FAN_SPEED_CMD.format(ss_id)) - - ss_read = raw_ss_read.split()[0] - rpm_speed = int(ss_read, 16)*150 - speed = int(float(rpm_speed)/max_rpm * 100) + status, output = self._api_helper.ipmi_raw(IPMI_SENSOR_NETFN,\ + IPMI_FAN_SPEED_CMD.format(self.sid_offset)) + if status: + raw_speed = output.split()[0] + rpm_speed = int(raw_speed, 16) * multiplier + speed = int((rpm_speed/self.max_speed) * 100) return speed @@ -120,8 +146,18 @@ class Fan(FanBase): 0 : when PWM mode is use pwm : when pwm mode is not use """ - target = 0 - return target + if self.is_psu_fan: + # Ignored for tolerance check + return self.get_speed() + + offset = hex(CPLD_REG_FANTRAY_BASE + (16 * self.fan_tray_index)) + status, output = self._api_helper.ipmi_raw(IPMI_OEM_NETFN,\ + IPMI_FAN_SPEED_CPLD_CMD.format(offset)) + if status: + fan_pwm = int(output, 16) + target_speed = int(fan_pwm / 255 * 100) + + return target_speed def get_speed_tolerance(self): """ @@ -130,7 +166,8 @@ class Fan(FanBase): An integer, the percentage of variance from target speed which is considered tolerable """ - return SPEED_TOLERANCE + + return FAN_SPEED_TOLERANCE def set_speed(self, speed): """ @@ -140,29 +177,10 @@ class Fan(FanBase): in the range 0 (off) to 100 (full speed) Returns: A boolean, True if speed is set successfully, False if not - Notes: - pwm setting mode must set as Manual - manual: ipmitool raw 0x3a 0x06 0x01 0x0 - auto: ipmitool raw 0x3a 0x06 0x01 0x1 """ - # ipmitool raw 0x3a 0x03 0x01 0x02 {register} {pwm_speed} - # register = 22 32 42 52 62 72 82 - if self.is_psu_fan: - # TODO - return False - - speed_hex = hex(int(float(speed)/100 * 255)) - fan_register_hex = hex(FAN_PWM_REGISTER_START + - (self.fan_tray_index*FAN_PWM_REGISTER_STEP)) - - set_speed_cmd = IPMI_SET_PWM.format(fan_register_hex, speed_hex) - status, set_speed_res = self._api_helper.ipmi_raw( - IPMI_OEM_NETFN, set_speed_cmd) - - set_speed = False if not status else True - - return set_speed + # FAN speed is controlled by BCM always + return False def set_status_led(self, color): """ @@ -180,7 +198,7 @@ class Fan(FanBase): """ if self.is_psu_fan: - # Not support + # Not supported for PSU return False led_cmd = { @@ -208,9 +226,9 @@ class Fan(FanBase): STATUS_LED_COLOR_RED = "red" STATUS_LED_COLOR_OFF = "off" """ - if self.is_psu_fan: - # Not support - return self.STATUS_LED_COLOR_OFF + if not self.get_presence() or self.is_psu_fan: + # Not supported for PSU + return "N/A" fan_selector = hex(int(FAN1_LED_CMD, 16) + self.fan_tray_index) status, hx_color = self._api_helper.ipmi_raw( @@ -224,16 +242,30 @@ class Fan(FanBase): return status_led + ############################################################## + ###################### Device methods ######################## + ############################################################## + def get_name(self): """ Retrieves the name of the device Returns: string: The name of the device """ - fan_name = FAN_NAME_LIST[self.fan_tray_index*2 + self.fan_index] if not self.is_psu_fan else "PSU-{} FAN-{}".format( - self.psu_index+1, self.fan_index+1) - return fan_name + if not self.name: + if not self.is_psu_fan: + psu_name = "" + fan_id = " {}".format(self.fan_tray_index + 1) + fan_type = " Front" if self.is_front else " Rear" + else: + psu_name = "PSU {} ".format(self.psu_index + 1) + fan_id = " {}".format(self.fan_tray_index + 1) + fan_type = "" + + self.name = FAN_NAME_TEMPLATE.format(psu_name, fan_id, fan_type) + + return self.name def get_presence(self): """ @@ -241,13 +273,12 @@ class Fan(FanBase): Returns: bool: True if FAN is present, False if not """ - if self.is_psu_fan: - return True presence = False - status, raw_present = self._api_helper.ipmi_raw( + + status, output = self._api_helper.ipmi_raw( IPMI_OEM_NETFN, IPMI_FAN_PRESENT_CMD.format(hex(self.index))) - if status and raw_present == "00": + if status and output == "00": presence = True return presence @@ -258,17 +289,13 @@ class Fan(FanBase): Returns: string: Model/part number of device """ - if self.is_psu_fan: - return "Unknown" + model = "N/A" - model = "Unknown" - ipmi_fru_idx = self.fan_tray_index + FAN1_FRU_ID - status, raw_model = self._api_helper.ipmi_fru_id( - ipmi_fru_idx, IPMI_FRU_MODEL_KEY) - - fru_pn_list = raw_model.split() - if len(fru_pn_list) > 4: - model = fru_pn_list[4] + if not self.is_psu_fan: + status, output = self._api_helper.ipmi_fru_id(FAN_FRU_ID_BASE + self.fan_tray_index, + "Board Part Number") + if status and output: + model = output.split(':')[-1].strip() return model @@ -278,17 +305,13 @@ class Fan(FanBase): Returns: string: Serial number of device """ - if self.is_psu_fan: - return "Unknown" + serial = "N/A" - serial = "Unknown" - ipmi_fru_idx = self.fan_tray_index + FAN1_FRU_ID - status, raw_model = self._api_helper.ipmi_fru_id( - ipmi_fru_idx, IPMI_FRU_SERIAL_KEY) - - fru_sr_list = raw_model.split() - if len(fru_sr_list) > 3: - serial = fru_sr_list[3] + if not self.is_psu_fan: + status, output = self._api_helper.ipmi_fru_id(FAN_FRU_ID_BASE + self.fan_tray_index, + "Board Serial") + if status and output: + serial = output.split(':')[-1].strip() return serial @@ -299,3 +322,24 @@ class Fan(FanBase): A boolean value, True if device is operating properly, False if not """ return self.get_presence() and self.get_speed() > 0 + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. + If the agent cannot determine the parent-relative position + for some reason, or if the associated value of + entPhysicalContainedIn is'0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device + or -1 if cannot determine the position + """ + + return self.fan_index + 1 + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True if not self.is_psu_fan else False diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/fan_drawer.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/fan_drawer.py new file mode 100644 index 0000000000..a7e5f167ad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/fan_drawer.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the the Fan-Drawers' information available in the platform +# +############################################################################# + +try: + from sonic_platform_base.fan_drawer_base import FanDrawerBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +NUM_FAN = 2 + + +class FanDrawer(FanDrawerBase): + def __init__(self, fantray_index): + FanDrawerBase.__init__(self) + self._index = fantray_index + 1 + self._init_fan(fantray_index) + + def _init_fan(self, fantray_index): + from sonic_platform.fan import Fan + for index in range(NUM_FAN): + fan = Fan(fantray_index, index) + self._fan_list.append(fan) + + def set_status_led(self, color): + """ + Sets the state of the fan drawer status LED + Args: + color: A string representing the color with which to set the + fan drawer status LED + Returns: + bool: True if status LED state is set successfully, False if not + """ + return self._fan_list[0].set_status_led(color) + + def get_status_led(self): + """ + Gets the state of the fan drawer LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + return self._fan_list[0].get_status_led() + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return "Drawer {}".format(self._index) + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return self._fan_list[0].get_presence() + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + return self._fan_list[0].get_model() + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + return self._fan_list[0].get_serial() + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self._fan_list[0].get_status() + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device + Returns: + integer: The 1-based relative physical position in parent device + """ + return self._index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/helper.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/helper.py new file mode 100644 index 0000000000..fcf077617b --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/helper.py @@ -0,0 +1,197 @@ +import fcntl +import os +import struct +import subprocess +from mmap import * + +from sonic_py_common import device_info + +HOST_CHK_CMD = "docker > /dev/null 2>&1" +EMPTY_STRING = "" + + +class APIHelper(): + + def __init__(self): + (self.platform, self.hwsku) = device_info.get_platform_and_hwsku() + + def is_host(self): + return os.system(HOST_CHK_CMD) == 0 + + def pci_get_value(self, resource, offset): + status = True + result = "" + try: + fd = os.open(resource, os.O_RDWR) + mm = mmap(fd, 0) + mm.seek(int(offset)) + read_data_stream = mm.read(4) + result = struct.unpack('I', read_data_stream) + except: + status = False + return status, result + + def run_command(self, cmd): + status = True + result = "" + try: + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + except: + status = False + return status, result + + def run_interactive_command(self, cmd): + try: + os.system(cmd) + except: + return False + return True + + def read_txt_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.read() + return data.strip() + except IOError: + pass + return None + + def read_one_line_file(self, file_path): + try: + with open(file_path, 'r') as fd: + data = fd.readline() + return data.strip() + except IOError: + pass + return None + + def write_txt_file(self, file_path, value): + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except Exception: + return False + return True + + def get_cpld_reg_value(self, getreg_path, register): + cmd = "echo {1} > {0}; cat {0}".format(getreg_path, register) + status, result = self.run_command(cmd) + return result if status else None + + def ipmi_raw(self, netfn, cmd): + status = True + result = "" + try: + cmd = "ipmitool raw {} {}".format(str(netfn), str(cmd)) + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result + + def ipmi_fru_id(self, id, key=None): + status = True + result = "" + try: + cmd = "ipmitool fru print {}".format(str( + id)) if not key else "ipmitool fru print {0} | grep '{1}' ".format(str(id), str(key)) + + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result + + def ipmi_set_ss_thres(self, id, threshold_key, value): + status = True + result = "" + try: + cmd = "ipmitool sensor thresh '{}' {} {}".format( + str(id), str(threshold_key), str(value)) + p = subprocess.Popen( + cmd, shell=True, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + raw_data, err = p.communicate() + if err == '': + result = raw_data.strip() + else: + status = False + except: + status = False + return status, result + + def lpc_getreg(self, getreg_path, reg): + """ + Get the cpld reg through lpc interface + + Args: + getreg_path: getreg sysfs path + reg: 16 bits reg addr in hex str format + + Returns: + A str, register value in hex str format + """ + try: + file = open(getreg_path, 'w+') + # Acquire an exclusive lock on the file + fcntl.flock(file, fcntl.LOCK_SH) + + file.write(reg) + file.flush() + + # Seek to the beginning of the file + file.seek(0) + + # Read the content of the file + result = file.readline().strip() + except (OSError, IOError, FileNotFoundError): + result = None + finally: + # Release the lock and close the file + fcntl.flock(file, fcntl.LOCK_UN) + file.close() + + return result + + def lpc_setreg(self, setreg_path, reg, val): + """ + Set the cpld reg through lpc interface + + Args: + setreg_path: setreg sysfs path + reg: 16 bits reg addr in hex str format + val: 8 bits register value in hex str format + + Returns: + A boolean, True if speed is set successfully, False if not + """ + status = True + try: + file = open(setreg_path, 'w') + # Acquire an exclusive lock on the file + fcntl.flock(file, fcntl.LOCK_EX) + + data = "{} {}".format(reg, val) + file.write(data) + file.flush() + except (OSError, IOError, FileNotFoundError): + status = False + finally: + # Release the lock and close the file + fcntl.flock(file, fcntl.LOCK_UN) + file.close() + + return status diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/pcie.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/pcie.py new file mode 100644 index 0000000000..0f8bc08303 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/pcie.py @@ -0,0 +1,15 @@ +# +# pcie_base.py +# +# Abstract base class for implementing platform-specific +# PCIE functionality for SONiC +# + +try: + from sonic_platform_base.sonic_pcie.pcie_common import PcieUtil +except ImportError as e: + raise ImportError (str(e) + " - required module not found") + +class Pcie(PcieUtil): + def __init__(self, platform_path): + PcieUtil.__init__(self, platform_path) diff --git a/device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/platform.py similarity index 100% rename from device/celestica/x86_64-cel_silverstone-r0/sonic_platform/platform.py rename to platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/platform.py diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/psu.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/psu.py new file mode 100644 index 0000000000..6a9faba3dc --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/psu.py @@ -0,0 +1,332 @@ +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the PSUs status which are available in the platform +# +############################################################################# + +try: + from sonic_platform_base.psu_base import PsuBase + from .helper import APIHelper + from sonic_platform.fan import Fan +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +IPMI_SENSOR_NETFN = "0x04" +IPMI_SENSOR_READ_CMD = "0x2D {}" +IPMI_SENSOR_THRESH_CMD = "0x27 {}" +IPMI_FRU_MODEL_KEY = "Board Part Number" +IPMI_FRU_SERIAL_KEY = "Board Serial" + +PSU_LED_OFF_CMD = "0x00" +PSU_LED_GREEN_CMD = "0x01" +PSU_LED_AMBER_CMD = "0x02" + +psu_ipmi_id = {\ + 1: {\ + "TEMP": "0x34",\ + "VOUT": "0x36",\ + "COUT": "0x37",\ + "POUT": "0x38",\ + "STATUS": "0x2f",\ + "FRU": 3,\ + }, + 2: {\ + "TEMP": "0x3E",\ + "VOUT": "0x40",\ + "COUT": "0x41",\ + "POUT": "0x42",\ + "STATUS": "0x39",\ + "FRU": 4,\ + } +} + +ANALOG_READ_OFFSET = 0 +EVENT_0_7_OFFSET = 2 +EVENT_8_14_OFFSET = 3 + +FRU_SERIAL = 3 +FRU_MODEL = 4 + +TH_LNC = 0 # Low Non-critical threshold +TH_LCR = 1 # Low Critical threshold +TH_LNR = 2 # Low Non-recoverable threshold +TH_HNC = 3 # High Non-critical threshold +TH_HCR = 4 # High Critical threshold +TH_HNR = 5 # High Non-recoverable threshold + + +class Psu(PsuBase): + """Platform-specific Psu class""" + + def __init__(self, psu_index): + PsuBase.__init__(self) + self.index = psu_index+1 + # PSU has only one FAN + fan = Fan(0, 0, is_psu_fan=True, psu_index=psu_index) + self._fan_list.append(fan) + self._api_helper = APIHelper() + + def get_voltage(self): + """ + Retrieves current PSU voltage output + Returns: + A float number, the output voltage in volts, + e.g. 12.1 + """ + psu_voltage = 0.0 + psu_vout_key = psu_ipmi_id[self.index]['VOUT'] + status, output = self._api_helper.ipmi_raw(IPMI_SENSOR_NETFN,\ + IPMI_SENSOR_READ_CMD.format(psu_vout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx6x10^-2 + psu_voltage = int(value, 16) * 6 / 100.0 + + return psu_voltage + + def get_current(self): + """ + Retrieves present electric current supplied by PSU + Returns: + A float number, the electric current in amperes, e.g 15.4 + """ + psu_current = 0.0 + psu_cout_key = psu_ipmi_id[self.index]['COUT'] + status, output = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_cout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx57x10^-2 + psu_current = int(value, 16) * 57 / 100.0 + + return psu_current + + def get_power(self): + """ + Retrieves current energy supplied by PSU + Returns: + A float number, the power in watts, e.g. 302.6 + """ + psu_power = 0.0 + psu_pout_key = psu_ipmi_id[self.index]['POUT'] + status, output = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pout_key)) + value = output.split()[ANALOG_READ_OFFSET] + # Formula: Rx68x10^-1 + psu_power = int(value, 16) * 68 / 10.0 + return psu_power + + def get_powergood_status(self): + """ + Retrieves the powergood status of PSU + Returns: + A boolean, True if PSU has stablized its output voltages and passed all + its internal self-tests, False if not. + """ + return self.get_status() + + def get_status_led(self): + """ + Gets the state of the PSU status LED + Returns: + A string, one of the predefined STATUS_LED_COLOR_* strings above + """ + if not self.get_presence(): + return "N/A" + + if self.get_powergood_status(): + return self.STATUS_LED_COLOR_GREEN + + return self.STATUS_LED_COLOR_OFF + + def __get_sensor_threshold(self, sensor_id, th_offset): + status, output = self._api_helper.ipmi_raw(IPMI_SENSOR_NETFN,\ + IPMI_SENSOR_THRESH_CMD.format(sensor_id)) + if status: + value = output.split() + if (int(value[0],16) >> th_offset) & 0x01 == 0x01: + return value[th_offset + 1] + + raise NotImplementedError + + def get_temperature(self): + """ + Retrieves current temperature reading from PSU + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + # PSU's ambient temperature sensor is considered as the PSU temperature + psu_temp = 0.0 + psu_temp_id = psu_ipmi_id[self.index]['TEMP'] + status, output = self._api_helper.ipmi_raw(IPMI_SENSOR_NETFN,\ + IPMI_SENSOR_READ_CMD.format(psu_temp_id)) + if status: + value = output.split()[ANALOG_READ_OFFSET] + psu_temp = float(int(value, 16)) + + return psu_temp + + def get_temperature_high_threshold(self): + """ + Retrieves the high threshold temperature of PSU + Returns: + A float number, the high threshold temperature of PSU in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + # Using critical-high as high threshold + + value = self.__get_sensor_threshold(psu_ipmi_id[self.index]['TEMP'], TH_HCR) + psu_temp_high_threshold = float(int(value, 16)) + + return psu_temp_high_threshold + + 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 + """ + # Using critical-high as high threshold + + value = self.__get_sensor_threshold(psu_ipmi_id[self.index]['VOUT'], TH_HCR) + # Formula: Rx6x10^-2 + psu_voltage_high_crit = int(value, 16) * 6 / 100.0 + + return psu_voltage_high_crit + + 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 + """ + # Using critical-low as low threshold + + value = self.__get_sensor_threshold(psu_ipmi_id[self.index]['VOUT'], TH_LCR) + # Formula: Rx6x10^-2 + psu_voltage_low_crit = int(value, 16) * 6 / 100.0 + + return psu_voltage_low_crit + + def get_maximum_supplied_power(self): + """ + Retrieves the maximum supplied power by PSU + Returns: + A float number, the maximum power output in Watts. + e.g. 1200.1 + """ + # Using critical-high as the maximum available safe power limit + + value = self.__get_sensor_threshold(psu_ipmi_id[self.index]['POUT'], TH_HCR) + # Formula: Rx12x10^0 + psu_power_high_crit = int(value, 16) * 12.0 + + return psu_power_high_crit + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return "PSU {}".format(self.index) + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + psu_presence = False + psu_pstatus_key = psu_ipmi_id[self.index]['STATUS'] + status, raw_status_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pstatus_key)) + status_byte = raw_status_read.split()[EVENT_0_7_OFFSET] + + if status: + psu_presence = True if int(status_byte, 16) & 0x01 == 0x01 else False + + return psu_presence + + def get_model(self): + """ + Retrieves the model number (or part number) of the device + Returns: + string: Model/part number of device + """ + model = "Unknown" + if self.get_presence(): + ipmi_fru_idx = psu_ipmi_id[self.index]['FRU'] + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_MODEL_KEY) + + fru_pn_list = raw_model.split() + if len(fru_pn_list) > FRU_MODEL: + model = fru_pn_list[FRU_MODEL] + else: + model = "N/A" + + return model + + def get_serial(self): + """ + Retrieves the serial number of the device + Returns: + string: Serial number of device + """ + serial = "Unknown" + if self.get_presence(): + ipmi_fru_idx = psu_ipmi_id[self.index]['FRU'] + status, raw_model = self._api_helper.ipmi_fru_id( + ipmi_fru_idx, IPMI_FRU_SERIAL_KEY) + + fru_sr_list = raw_model.split() + if len(fru_sr_list) > FRU_SERIAL: + serial = fru_sr_list[FRU_SERIAL] + else: + model = "N/A" + + return serial + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + psu_status = False + psu_pstatus_key = psu_ipmi_id[self.index]['STATUS'] + status, raw_status_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SENSOR_READ_CMD.format(psu_pstatus_key)) + status_byte = raw_status_read.split()[EVENT_0_7_OFFSET] + + if status: + failure_detected = True if int(status_byte, 16) & 0x02 == 0x02 else False + input_lost = True if int(status_byte, 16) & 0x08 == 0x08 else False + psu_status = False if (input_lost or failure_detected) else True + + return psu_status + + def get_position_in_parent(self): + """ + Retrieves 1-based relative physical position in parent device. If the agent cannot determine the parent-relative position + for some reason, or if the associated value of entPhysicalContainedIn is '0', then the value '-1' is returned + Returns: + integer: The 1-based relative physical position in parent device or -1 if cannot determine the position + """ + return self.index + + def is_replaceable(self): + """ + Indicate whether this device is replaceable. + Returns: + bool: True if it is replaceable. + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/sfp.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/sfp.py new file mode 100644 index 0000000000..204ee659f9 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/sfp.py @@ -0,0 +1,232 @@ +#!/usr/bin/env python + +############################################################################# +# Celestica +# +# Module contains an implementation of SONiC Platform Base API and +# provides the sfp status which are available in the platform +# +############################################################################# + +import time + +try: + from sonic_platform_base.sonic_xcvr.sfp_optoe_base import SfpOptoeBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +SFP_I2C_START = 10 +I2C_EEPROM_PATH = '/sys/bus/i2c/devices/i2c-{0}/{0}-0050/eeprom' +RESET_PATH = '/sys/devices/platform/cls-xcvr/hwmon/hwmon{0}/qsfp_resetL' +LP_PATH = '/sys/devices/platform/cls-xcvr/hwmon/hwmon{0}/qsfp_lpmode' +PRS_PATH = '/sys/devices/platform/cls-xcvr/hwmon/hwmon{0}/qsfp_modprsL' + + +class Sfp(SfpOptoeBase): + """Platform-specific SfpOptoe class""" + + def __init__(self, sfp_index=0, sfp_name=None): + SfpOptoeBase.__init__(self) + + self.index = sfp_index + 1 + self._api_helper = APIHelper() + self._name = sfp_name + self._sfp_type = None + + def _detect_sfp_type(self): + sfp_type = 'N/A' + info = self.get_transceiver_info() + if info: + sfp_type = info.get("type_abbrv_name") + # XXX: Need this hack until xcvrd is refactored + if sfp_type in ["OSFP-8X", "QSFP-DD"]: + sfp_type = "QSFP_DD" + return sfp_type + + @property + def sfp_type(self): + if self._sfp_type is None: + self._sfp_type = self._detect_sfp_type() + return self._sfp_type + + def get_eeprom_path(self): + port_to_i2c_mapping = SFP_I2C_START + self.index - 1 + port_eeprom_path = I2C_EEPROM_PATH.format(port_to_i2c_mapping) + return port_eeprom_path + + def get_name(self): + """ + Retrieves the name of the device + Returns: + string: The name of the device + """ + return self._name + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + if not self.get_presence(): + return False + reset = self.get_reset_status() + if reset: + status = False + else: + status = True + return status + + def get_reset_status(self): + """ + Retrieves the reset status of SFP + Returns: + A Boolean, True if reset enabled, False if disabled + """ + reset_status_raw = self._api_helper.read_txt_file( + RESET_PATH.format((self.index))).rstrip() + if not reset_status_raw: + return False + + reg_value = int(reset_status_raw, 16) + bin_format = bin(reg_value)[2:].zfill(32) + return bin_format[::-1][self.index - 1] == '0' + + def get_presence(self): + """ + Retrieves the presence of the PSU + Returns: + bool: True if PSU is present, False if not + """ + presence_status_raw = self._api_helper.read_txt_file( + PRS_PATH.format((self.index))).rstrip() + + if not presence_status_raw: + return False + + content = presence_status_raw.rstrip() + reg_value = int(content, 16) + + + # Mask absent + absence_mask = 0x1 + + # ModPrsL is active low + if reg_value & absence_mask == 0: + return True + + return False + + def get_lpmode(self): + """ + Retrieves the lpmode (low power mode) status of this SFP + Returns: + A Boolean, True if lpmode is enabled, False if disabled + """ + try: + with open(LP_PATH.format((self.index))) as reg_file: + content = reg_file.readline().rstrip() + lpmode = int(content, 16) + except (ValueError, IOError) as e: + return False + + # check LPMode is active low + if lpmode == 0: + return False + + return True + + def reset(self): + """ + Reset SFP and return all user module settings to their default srate. + Returns: + A boolean, True if successful, False if not + """ + # Check for invalid port_num + + try: + reg_file = open(RESET_PATH.format((self.index)), "r+") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + content = reg_file.readline().rstrip() + + # File content is a string containing the hex representation of the + # register + reg_value = int(content, 16) + + # Determind if port_num start from 1 or 0 + bit_index = self.index - 1 + + # Mask off the bit corresponding to our port + mask = (1 << bit_index) + + # ResetL is active low + reg_value = reg_value & ~mask + + # Convert our register value back to a hex string and write back + reg_file.seek(0) + reg_file.write(hex(reg_value).rstrip('L')) + reg_file.close() + + # Sleep 1 second to allow it to settle + time.sleep(1) + + # Flip the bit back high and write back to the register + # to take port out of reset + try: + reg_file = open(RESET_PATH.format((self.index)), "w") + except IOError as e: + print("Error: unable to open file: %s" % str(e)) + return False + + reg_value = reg_value | mask + reg_file.seek(0) + reg_file.write(hex(reg_value).rstrip('L')) + reg_file.close() + + return True + + def set_lpmode(self, lpmode): + """ + Sets the lpmode (low power mode) of SFP + Args: + lpmode: A Boolean, True to enable lpmode, False to disable it + Note : lpmode can be overridden by set_power_override + Returns: + A boolean, True if lpmode is set successfully, False if not + """ + try: + with open(LP_PATH.format((self.index)), "r+") as reg_file: + reg_file.seek(0) + content = hex(lpmode) + reg_file.write(content) + except IOError as e: + return False + + return True + + def get_error_description(self): + """ + Retrives the error descriptions of the SFP module + Returns: + String that represents the current error descriptions of + vendor specific errors + In case there are multiple errors, they should be joined by '|', + like: "Bad EEPROM|Unsupported cable" + """ + if self.sfp_type == "QSFP_DD": + return super().get_error_description() + + if not self.get_presence(): + return self.SFP_STATUS_UNPLUGGED + return self.SFP_STATUS_OK + + def get_position_in_parent(self): + return self.index + + def is_replaceable(self): + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/thermal.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/thermal.py new file mode 100644 index 0000000000..9f0c9e17ad --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/thermal.py @@ -0,0 +1,205 @@ +############################################################################# +# Celestica +# +# Thermal contains an implementation of SONiC Platform Base API and +# provides the thermal device status which are available in the platform +# +############################################################################# + +import os +import re +import os.path + +try: + from sonic_platform_base.thermal_base import ThermalBase + from .helper import APIHelper +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + +IPMI_SENSOR_NETFN = "0x04" +IPMI_SS_READ_CMD = "0x2D {}" +IPMI_SS_THRESHOLD_CMD = "0x27 {}" +HIGH_TRESHOLD_SET_KEY = "unc" +DEFAULT_VAL = 'N/A' + +class Thermal(ThermalBase): + """Platform-specific Thermal class""" + + def __init__(self, thermal_index): + ThermalBase.__init__(self) + self._api_helper = APIHelper() + self.index = thermal_index + thermal_list = [\ + ('TEMP_FAN_U52', '0x00', 'Fanboard Center Temp'),\ + ('TEMP_FAN_U17', '0x01', 'Fanboard Right Temp'),\ + ('TEMP_SW_U52', '0x02', 'Switchboard Left Temp'),\ + ('TEMP_SW_U16', '0x03', 'Switchboard Right Temp'),\ + ('TEMP_BB_U3', '0x04', 'Baseboard Temp'),\ + ('TEMP_CPU', '0x05', 'CPU Internal Temp'),\ + ('TEMP_SW_Internal', '0x61', 'ASIC Internal Temp'),\ + ('SW_U04_Temp', '0x4F', 'IR35215 Chip Left Temp'),\ + ('SW_U14_Temp', '0x56', 'IR35215 Chip Right Temp'),\ + ('SW_U4403_Temp', '0x5D', 'IR3584 Chip Temp'),\ + ('PSU1_Temp1', '0x34', 'PSU 1 Ambient Temp'),\ + ('PSU1_Temp2', '0x35', 'PSU 1 Hotspot Temp'),\ + ('PSU2_Temp1', '0x3E', 'PSU 2 Ambient Temp'),\ + ('PSU2_Temp2', '0x3F', 'PSU 2 Hotspot Temp'),\ + ] + self.sensor_id = thermal_list[self.index][0] + self.sensor_reading_addr = thermal_list[self.index][1] + self.sensor_name = thermal_list[self.index][2] + + temp = self.get_temperature(True) + self.minimum_thermal = temp + self.maximum_thermal = temp + + def get_temperature(self, skip_record=False): + """ + Retrieves current temperature reading from thermal + Returns: + A float number of current temperature in Celsius up to nearest thousandth + of one degree Celsius, e.g. 30.125 + """ + temperature = 0.0 + status, raw_ss_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_READ_CMD.format(self.sensor_reading_addr)) + if status and len(raw_ss_read.split()) > 0: + ss_read = raw_ss_read.split()[0] + temperature = float(int(ss_read, 16)) + + if temperature != 0.0: + if not skip_record: + # Record maximum + if temperature > self.maximum_thermal: + self.maximum_thermal = temperature + + # Record minimum + if temperature < self.minimum_thermal: + self.minimum_thermal = temperature + + return temperature + else: + return DEFAULT_VAL + + def get_high_threshold(self): + """ + Retrieves the high threshold temperature of thermal + Returns: + A float number, the high threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + high_threshold = 0.0 + status, raw_up_thres_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_THRESHOLD_CMD.format(self.sensor_reading_addr)) + if status and len(raw_up_thres_read.split()) > 6: + ss_read = raw_up_thres_read.split()[4] + high_threshold = float(int(ss_read, 16)) + if high_threshold != 0.0: + return high_threshold + else: + return DEFAULT_VAL + + def get_low_threshold(self): + """ + Retrieves the low threshold temperature of thermal + Returns: + A float number, the low threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return DEFAULT_VAL + + def set_high_threshold(self, temperature): + """ + Sets the high threshold temperature of thermal + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if not + """ + status, ret_txt = self._api_helper.ipmi_set_ss_thres( + self.sensor_id, HIGH_TRESHOLD_SET_KEY, temperature) + return status + + def set_low_threshold(self, temperature): + """ + Sets the low threshold temperature of thermal + Args : + temperature: A float number up to nearest thousandth of one degree Celsius, + e.g. 30.125 + Returns: + A boolean, True if threshold is set successfully, False if not + """ + return False + + def get_high_critical_threshold(self): + """ + Retrieves the high critical threshold temperature of thermal + Returns: + A float number, the high critical threshold temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + high_critical_threshold = 0.0 + status, raw_up_thres_read = self._api_helper.ipmi_raw( + IPMI_SENSOR_NETFN, IPMI_SS_THRESHOLD_CMD.format(self.sensor_reading_addr)) + if status and len(raw_up_thres_read.split()) > 6: + ss_read = raw_up_thres_read.split()[5] + high_critical_threshold = float(int(ss_read, 16)) + if high_critical_threshold != 0.0: + return high_critical_threshold + else: + return DEFAULT_VAL + + def get_minimum_recorded(self): + """ + Retrieves the minimum recorded temperature of thermal + Returns: + A float number, the minimum recorded temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self.minimum_thermal + + def get_maximum_recorded(self): + """ + Retrieves the maximum recorded temperature of thermal + Returns: + A float number, the maximum recorded temperature of thermal in Celsius + up to nearest thousandth of one degree Celsius, e.g. 30.125 + """ + return self.maximum_thermal + + ############################################################## + ###################### Device methods ######################## + ############################################################## + + def get_name(self): + """ + Retrieves the name of the thermal device + Returns: + string: The name of the thermal device + """ + return self.sensor_name + + def get_presence(self): + """ + Retrieves the presence of the device + Returns: + bool: True if device is present, False if not + """ + return True if self.get_temperature() > 0 else False + + def get_status(self): + """ + Retrieves the operational status of the device + Returns: + A boolean value, True if device is operating properly, False if not + """ + return self.get_presence() + + def is_replaceable(self): + """ + Retrieves whether thermal module is replaceable + Returns: + A boolean value, True if replaceable, False if not + """ + return False diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/thermal_manager.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/thermal_manager.py new file mode 100644 index 0000000000..5c70ccc80e --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/thermal_manager.py @@ -0,0 +1,21 @@ +from sonic_platform_base.sonic_thermal_control.thermal_manager_base import ThermalManagerBase + + +class ThermalManager(ThermalManagerBase): + @classmethod + def initialize(cls): + """ + Initialize thermal manager, including register thermal condition types and thermal action types + and any other vendor specific initialization. + :return: + """ + return True + + @classmethod + def deinitialize(cls): + """ + Destroy thermal manager, including any vendor specific cleanup. The default behavior of this function + is a no-op. + :return: + """ + return True diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/watchdog.py b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/watchdog.py new file mode 100644 index 0000000000..011759b0f4 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/sonic_platform/watchdog.py @@ -0,0 +1,247 @@ +############################################################################# +# Celestica Silverstone +# +# Watchdog contains an implementation of SONiC Platform Base API +# +############################################################################# +import os +import time +import ctypes +import fcntl +import subprocess +import array +import syslog + +try: + from sonic_platform_base.watchdog_base import WatchdogBase +except ImportError as e: + raise ImportError(str(e) + "- required module not found") + + +PLATFORM_CPLD_PATH = '/sys/devices/platform/baseboard-lpc/' +WDT_TIMER_REG = '0xA181' +WDT_ENABLE_REG = '0xA182' +WDT_FEED_REG = '0xA183' +WDT_REMAINTIME_REG1 = '0xA185' +WDT_REMAINTIME_REG2 = '0xA186' +ENABLE_CMD = 0x1 +DISABLE_CMD = 0x0 +WDT_COMMON_ERROR = -1 + + +class Watchdog(WatchdogBase): + + timeout = 0 + + def __init__(self): + WatchdogBase.__init__(self) + + # Set default value + #self._disable() + #self.timeout = self._gettimeout() + self.keepalive = int(1) + + def _get_lpc_reg(self, reg): + file_path = os.path.join(PLATFORM_CPLD_PATH, 'getreg') + status = True + value = None + + try: + with open(file_path, "r+") as fd: + fd.seek(0) + fd.write(reg) + except IOError as e: + syslog.syslog(syslog.LOG_ERR, "Unable to access file: {}".format(e)) + return False, None + try: + with open(file_path) as fd: + value = fd.readline().rstrip() + except IOError as e: + syslog.syslog(syslog.LOG_ERR, "Unable to access file: {}".format(e)) + return False, None + return True, value + + def _set_lpc_reg(self, reg, val): + file_path = os.path.join(PLATFORM_CPLD_PATH, 'setreg') + value = '{} {}'.format(reg, hex(val)) + + try: + with open(file_path, 'w') as fd: + fd.write(str(value)) + except Exception: + return False + return True + + def _enable(self): + """ + Turn on the watchdog timer + """ + # echo 0xA182 0x1 > /sys/devices/platform/baseboard-lpc/setreg + status = self._set_lpc_reg(WDT_ENABLE_REG, ENABLE_CMD) + + if not status: + return False + + return True + + def _disable(self): + """ + Trun off the watchdog timer + """ + # echo 0xA182 0x0 > /sys/devices/platform/baseboard-lpc/setreg + status = self._set_lpc_reg(WDT_ENABLE_REG, DISABLE_CMD) + if not status: + return False + + return True + + def _keepalive(self): + """ + Keep alive watchdog timer + """ + if bool(self.keepalive % 2): + status = self._set_lpc_reg(WDT_FEED_REG, ENABLE_CMD) + else: + status = self._set_lpc_reg(WDT_FEED_REG, DISABLE_CMD) + + if not status: + syslog.syslog(syslog.LOG_ERR, "Feed Watchdog failed") + + self.keepalive = self.keepalive+1 + if (self.keepalive >= 11): + self.keepalive = 1 + + def _settimeout(self, seconds): + """ + set watchdog timer timeout + @param seconds - timeout in seconds + @return is the actual set timeout + """ + second_int = { + 30: 1, + 60: 2, + 180: 3, + 240: 4, + 300: 5, + 420: 6, + 600: 7, + }.get(seconds) + + status = self._set_lpc_reg(WDT_TIMER_REG, second_int) + if not status: + syslog.syslog(syslog.LOG_ERR, "Set timeout failed") + return self._gettimeout() + + def _gettimeout(self): + """ + Get watchdog timeout + @return watchdog timeout + """ + status, data = self._get_lpc_reg(WDT_TIMER_REG) + if status: + pass + + bin_val = bin(int(data, 16))[2:].zfill(3) + + return { + '001': 30, + '010': 60, + '011': 180, + '100': 240, + '101': 300, + '110': 420, + '111': 600, + }.get(bin_val) + + def arm(self, seconds): + """ + Arm the hardware watchdog with a timeout of seconds. + If the watchdog is currently armed, calling this function will + simply reset the timer to the provided value. If the underlying + hardware does not support the value provided in , this + method should arm the watchdog with the *next greater* available + value. + Returns: + An integer specifying the *actual* number of seconds the watchdog + was armed with. On failure returns -1. + """ + avaliable_second = [30, 60, 180, 240, 300, 420, 600] + ret = WDT_COMMON_ERROR + + if seconds < 0 or seconds not in avaliable_second: + return ret + + try: + if self.timeout != seconds: + self.timeout = self._settimeout(seconds) + + if self.is_armed(): + self._keepalive() + else: + status = self._enable() + if not status: + syslog.syslog(syslog.LOG_ERR, "Enable watchdog failed") + return ret + + ret = self.timeout + except IOError as e: + syslog.syslog(syslog.LOG_ERR, "{}".format(e)) + + return ret + + def disarm(self): + """ + Disarm the hardware watchdog + Returns: + A boolean, True if watchdog is disarmed successfully, False if not + """ + disarmed = False + if self.is_armed(): + try: + status = self._disable() + if status: + disarmed = True + except IOError: + syslog.syslog(syslog.LOG_ERR, "{}".format(e)) + + return disarmed + + + def is_armed(self): + """ + Retrieves the armed state of the hardware watchdog. + Returns: + A boolean, True if watchdog is armed, False if not + """ + status, data = self._get_lpc_reg(WDT_ENABLE_REG) + if status: + pass + + armed = int(data, 16) & 0x1 + + return bool(armed) + + def get_remaining_time(self): + """ + If the watchdog is armed, retrieve the number of seconds remaining on + the watchdog timer + Retruns: + An integer specifying the number of seconds remaining on the + watchdog timer. If the watchdog is not armed, returns -1 + """ + retime = 0 + + status, data1 = self._get_lpc_reg(WDT_REMAINTIME_REG1) + if status: + pass + + status, data2 = self._get_lpc_reg(WDT_REMAINTIME_REG2) + if status: + pass + + retime = (int(data2,16) & 0xff) + ((int(data1,16) & 0x3f) * 256) + + if retime <= 0: + return WDT_COMMON_ERROR + else: + return int(retime/10) From 382f5919a17b0d56c8df2fb8b0db760032ce10d2 Mon Sep 17 00:00:00 2001 From: Jemston Fernando Date: Tue, 6 Feb 2024 07:26:11 +0000 Subject: [PATCH 2/3] Fix funtion return type in Driver --- platform/broadcom/sonic-platform-modules-cel/debian/control | 2 +- .../debian/platform-modules-questone2.install | 1 - .../sonic-platform-modules-cel/questone2/modules/mc24lc64t.c | 4 +--- .../sonic-platform-modules-cel/questone2/modules/optoe.c | 3 +-- .../questone2/modules/sff_8436_eeprom.c | 3 +-- .../silverstone/modules/cls-i2c-mux-pca954x.c | 3 +-- .../silverstone/modules/switch_cpld.c | 3 +-- 7 files changed, 6 insertions(+), 13 deletions(-) diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/control b/platform/broadcom/sonic-platform-modules-cel/debian/control index cef0dfd391..93a049626f 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/control +++ b/platform/broadcom/sonic-platform-modules-cel/debian/control @@ -28,7 +28,7 @@ Description: kernel modules for platform devices such as led, sfp. Package: platform-modules-ds1000 Architecture: amd64 -Depends: linux-image-5.10.0-23-2-amd64-unsigned +Depends: linux-image-6.1.0-11-2-amd64-unsigned Description: kernel modules for platform devices such as led, sfp Package: platform-modules-questone2 diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.install b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.install index 1b6114d360..b08bfe00d4 100644 --- a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.install +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.install @@ -7,4 +7,3 @@ questone2/scripts/questone2_platform_shutdown.sh usr/local/bin questone2/scripts/sensors usr/bin questone2/scripts/platform_sensors.py usr/local/bin services/platform_api/platform_api_mgnt.sh usr/local/bin -services/platform_api/ps_mem.py usr/local/bin diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/mc24lc64t.c b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/mc24lc64t.c index ae79770a4d..4603b3d410 100644 --- a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/mc24lc64t.c +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/mc24lc64t.c @@ -142,12 +142,10 @@ static int mc24lc64t_probe(struct i2c_client *client, return err; } -static int mc24lc64t_remove(struct i2c_client *client) +static void mc24lc64t_remove(struct i2c_client *client) { struct mc24lc64t_data *drvdata = i2c_get_clientdata(client); sysfs_remove_bin_file(&client->dev.kobj, &mc24lc64t_bit_attr); - - return 0; } static const struct i2c_device_id mc24lc64t_id[] = { diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/optoe.c b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/optoe.c index a16bdfc96a..cfddaa07cb 100644 --- a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/optoe.c +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/optoe.c @@ -780,7 +780,7 @@ static ssize_t optoe_bin_write(struct file *filp, struct kobject *kobj, return optoe_read_write(optoe, buf, off, count, OPTOE_WRITE_OP); } -static int optoe_remove(struct i2c_client *client) +static void optoe_remove(struct i2c_client *client) { struct optoe_data *optoe; int i; @@ -798,7 +798,6 @@ static int optoe_remove(struct i2c_client *client) kfree(optoe->writebuf); kfree(optoe); - return 0; } static ssize_t show_dev_class(struct device *dev, diff --git a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff_8436_eeprom.c b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff_8436_eeprom.c index 6779ccee5e..70dc2ba272 100644 --- a/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff_8436_eeprom.c +++ b/platform/broadcom/sonic-platform-modules-cel/questone2/modules/sff_8436_eeprom.c @@ -777,7 +777,7 @@ static ssize_t sff_8436_bin_write(struct file *filp, struct kobject *kobj, /*-------------------------------------------------------------------------*/ -static int sff_8436_remove(struct i2c_client *client) +static void sff_8436_remove(struct i2c_client *client) { struct sff_8436_data *sff_8436; @@ -786,7 +786,6 @@ static int sff_8436_remove(struct i2c_client *client) kfree(sff_8436->writebuf); kfree(sff_8436); - return 0; } static int sff_8436_eeprom_probe(struct i2c_client *client, const struct i2c_device_id *id) diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-i2c-mux-pca954x.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-i2c-mux-pca954x.c index 71b635f326..87c51c15ad 100644 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-i2c-mux-pca954x.c +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/cls-i2c-mux-pca954x.c @@ -533,14 +533,13 @@ fail_cleanup: return ret; } -static int pca954x_remove(struct i2c_client *client) +static void pca954x_remove(struct i2c_client *client) { struct i2c_mux_core *muxc = i2c_get_clientdata(client); device_remove_file(&client->dev, &dev_attr_idle_state); pca954x_cleanup(muxc); - return 0; } #ifdef CONFIG_PM_SLEEP diff --git a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switch_cpld.c b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switch_cpld.c index 7a0abc27e5..b1900d0324 100644 --- a/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switch_cpld.c +++ b/platform/broadcom/sonic-platform-modules-cel/silverstone/modules/switch_cpld.c @@ -381,7 +381,7 @@ exit: return err; } -static int switch_cpld_remove(struct i2c_client *client) +static void switch_cpld_remove(struct i2c_client *client) { struct switch_cpld_data *data = i2c_get_clientdata(client); @@ -389,7 +389,6 @@ static int switch_cpld_remove(struct i2c_client *client) sysfs_remove_link(&data->client2->dev.kobj, "CPLD2"); sysfs_remove_link(&client->dev.kobj, "CPLD1"); i2c_unregister_device(data->client2); - return 0; } static const struct i2c_device_id switch_cpld_ids[] = { From f811c883896f7e1c6d16d743fa8aeef2ffc5a3bc Mon Sep 17 00:00:00 2001 From: Jemston Fernando Date: Tue, 27 Feb 2024 18:16:33 +0000 Subject: [PATCH 3/3] Force commit the git ignored platform init script --- .../debian/platform-modules-questone2.init | 97 +++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.init diff --git a/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.init b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.init new file mode 100644 index 0000000000..a32be9dd97 --- /dev/null +++ b/platform/broadcom/sonic-platform-modules-cel/debian/platform-modules-questone2.init @@ -0,0 +1,97 @@ +#!/bin/bash + +### BEGIN INIT INFO +# Provides: setup-board +# Required-Start: $portmap +# Required-Stop: +# Should-Start: +# Should-Stop: +# Default-Start: S +# Default-Stop: 0 6 +# Short-Description: Setup questone2 board. +### END INIT INFO + + +case "$1" in +start) + echo -n "Setting up board... " + + # Loads kernel modules + modprobe i2c-ismt + modprobe i2c-i801 + modprobe i2c-isch + modprobe i2c-dev + modprobe i2c-mux + modprobe i2c-smbus + modprobe i2c-mux-gpio + modprobe i2c-mux-pca954x + modprobe 8021q + + modprobe questone2_baseboard_cpld + modprobe questone2_switchboard + modprobe mc24lc64t + modprobe optoe + modprobe sff_8436_eeprom + + # Add driver to support TLV - EEPROM + for devnum in 0 1; do + devname=`cat /sys/bus/i2c/devices/i2c-${devnum}/name` + if [[ $devname == 'SMBus iSMT adapter at '* ]]; then + echo 24lc64t 0x56 > /sys/bus/i2c/devices/i2c-${devnum}/new_device + echo -n "/sys/bus/i2c/devices/i2c-${devnum}" > /tmp/eeprom_path.txt + break + fi + done + + # One platform support two hwskus, auto select the correct hwsku + # If label is not either Questone-II or Questone-IIA, then Questone-IIA is used by default + hwsku_file="/usr/share/sonic/device/x86_64-cel_questone_2-r0/default_sku" + if [ ! -f $hwsku_file ]; then + platform_path="/usr/share/sonic/device/x86_64-cel_questone_2-r0" + + sleep 1 # Wait for EEPROM driver initialization + hwsku=$(decode-syseeprom | grep "Label" | awk '{print $5}') + + cd ${platform_path} + if [ x$hwsku = x"Questone-II" ];then + echo "Questone_2 t1" > $hwsku_file + ln -sf ./Questone_2/platform.json platform.json + ln -sf ./Questone_2/platform_components.json platform_components.json + ln -sf ./Questone_2/custom_led.bin custom_led.bin + else + echo "Questone_2A t1" > $hwsku_file + ln -sf ./Questone_2A/platform.json platform.json + ln -sf ./Questone_2A/platform_components.json platform_components.json + ln -sf ./Questone_2A/custom_led.bin custom_led.bin + fi + fi + + # SONiC LED control policy + ipmitool raw 0x3a 0x0f 0x02 0x00 + # Set status led to green blinking 1Hz to indicate NOS take control + ipmitool raw 0x3a 0x0a 0x00 0x06 + # Set Alarm LED off + ipmitool raw 0x3a 0x0c 0x00 0x03 0x63 0x00 + # PSU and FAN LED are in default controlled by CPLD + + echo "done." + ;; + +stop) + if [ -f /tmp/eeprom_path.txt ]; then + echo 0x56 > `cat /tmp/eeprom_path.txt`/delete_device + fi + echo "done." + ;; + +force-reload|restart) + echo "Not supported" + ;; + +*) + echo "Usage: /etc/init.d/platform-modules-questone2 {start|stop}" + exit 1 + ;; +esac + +exit 0